下面的代码没有编译,但说明了我想要做的事情: totalTests应该保存调用assertEquals()的时间(assertEquals()可能是一个宏,但我还不熟悉Nim的这个方面)。
您知道如何修改这些代码以使以下代码能够在每个测试报告行的开头打印1/2和2/2吗?
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)编辑:在代码中添加问题
发布于 2015-05-12 21:39:20
这里有一种方法。可以使用宏或static语句在编译时执行代码。请注意,仍然无法在多个模块中可靠地计算这些数据。
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()另一种实现是将测试嵌入自定义块语句中。
testSuite:
assertEquals("test #A", 12, proc(): int = 14-2)
assertEquals("test #B", 12, proc(): int = 12-2)然后,testSuite宏将计算嵌入代码中的断言,并相应地初始化变量。
另一个解决方案是不直接执行测试,而是将它们存储在一个列表中,然后只在最后执行它们。
发布于 2015-05-13 02:12:34
以下是Reimer第三项建议的实施,这对我来说是最有效的。
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()https://stackoverflow.com/questions/30200676
复制相似问题