首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nim中的编译时呼叫计数

Nim中的编译时呼叫计数
EN

Stack Overflow用户
提问于 2015-05-12 20:19:44
回答 2查看 410关注 0票数 5

下面的代码没有编译,但说明了我想要做的事情: totalTests应该保存调用assertEquals()的时间(assertEquals()可能是一个宏,但我还不熟悉Nim的这个方面)。

您知道如何修改这些代码以使以下代码能够在每个测试报告行的开头打印1/2和2/2吗?

代码语言:javascript
复制
from strutils import format

var countTested = 0
var countFailed = 0
var countPassed = 0
let totalTests = 0 # <-- need let or other compile-time type here (?)

# using proc here... macro may be needed to be able to count calls (?)
proc assertEquals*[T](testName: string, expected: T, p: (proc(): T)) =
   countTested += 1
   totalTests += 1 # <-- compilation error (how can we increase each time it is called?)
   write(stdout, format("[$num/$total] $name: ", "num", countTested, "total", totalTests, "name", testName))
   var val = p()
   if val == expected:
     write(stdout, "passed\n")
     countPassed += 1
   else:
     write(stdout, "failed\n")
     countFailed += 1

when isMainModule:
  assertEquals("test #A", 12, proc(): int = 14-2)
  assertEquals("test #B", 12, proc(): int = 12-2)

编辑:在代码中添加问题

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-12 21:39:20

这里有一种方法。可以使用宏或static语句在编译时执行代码。请注意,仍然无法在多个模块中可靠地计算这些数据。

代码语言:javascript
复制
import macros, strutils

proc beginTests()

var countTested = 0
var countFailed = 0
var countPassed = 0
var totalTests = 0
var totalTestsCT {.compiletime.} = 0

macro endTests(): stmt =
  quote do:
    proc beginTests() =
      totalTests = `totalTestsCT`

proc assertEqualsImpl*[T](testName: string, expected: T, p: (proc(): T)) =
   countTested += 1
   write(stdout, format("[$num/$total] $name: ",
         "num", countTested, "total", totalTests, "name", testName))
   var val = p()
   if val == expected:
     write(stdout, "passed\n")
     countPassed += 1
   else:
     write(stdout, "failed\n")
     countFailed += 1

macro assertEquals*[T](testName: string, expected: T, p: (proc(): T)): stmt =
  totalTestsCT += 1
  quote do:
    assertEqualsImpl(`testName`, `expected`, `p`)

when isMainModule:
  beginTests()
  assertEquals("test #A", 12, proc(): int = 14-2)
  assertEquals("test #B", 12, proc(): int = 12-2)
  endTests()

另一种实现是将测试嵌入自定义块语句中。

代码语言:javascript
复制
testSuite:
  assertEquals("test #A", 12, proc(): int = 14-2)
  assertEquals("test #B", 12, proc(): int = 12-2)

然后,testSuite宏将计算嵌入代码中的断言,并相应地初始化变量。

另一个解决方案是不直接执行测试,而是将它们存储在一个列表中,然后只在最后执行它们。

票数 5
EN

Stack Overflow用户

发布于 2015-05-13 02:12:34

以下是Reimer第三项建议的实施,这对我来说是最有效的。

代码语言:javascript
复制
import macros, strutils

type 
  TestSuiteObj = object
    countTested: int
    countFailed: int
    countPassed: int
    totalTests: int
    tests: seq[(proc (self: TestSuite))]
  TestSuite* = ref TestSuiteObj


proc newTestSuite*(): TestSuite =
  new(result)
  result.countTested = 0
  result.countFailed = 0
  result.countPassed = 0
  result.totalTests = 0
  result.tests = @[]

proc assertEquals*[T](self: TestSuite, testName: string, expected: T, p: (proc(): T)) =
  self.totalTests += 1

  var testProc = proc(self: TestSuite) =
    self.countTested += 1
    write(stdout, format("[$num/$total] $name: ", "num", self.countTested, "total", self.totalTests, "name", testName))
    var val = p()
    if val == expected:
      write(stdout, "passed\n")
      self.countPassed += 1
    else:
      write(stdout, "failed\n")
      self.countFailed += 1

  self.tests.add(testProc)


proc run*(self: TestSuite) =
  self.totalTests = self.tests.len
  for p in self.tests:
    p(self)

  var verdict = case (self.countTested == self.countPassed)
  of true: "PASSED"
  of false: "FAILED"
  echo format("$verdict. Passed [$passed/$total] tests.", "verdict", verdict, "passed", self.countPassed, "total", self.countTested)

  # Sanity
  assert(self.countTested == (self.countFailed+self.countPassed))
  assert(self.countTested == self.totalTests)


when isMainModule:
  var suite = newTestSuite() 
  suite.assertEquals("test #A", 12, proc(): int = 14-2)
  suite.assertEquals("test #B", 12, proc(): int = 12-2)
  suite.run()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30200676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档