动态生成机架单元测试套件:测试通过并引发异常
Dynamically generating rackunit test-suite: tests pass and also raise exception
我正在尝试动态生成一堆测试用例。
基本上我想运行用不同的值多次相同的测试。也许有更好的方法,如果有请告诉我,我还没有找到。
我发现 make-test-suite
说你可以向它传递 test-case
个实例的列表。
所以我做了一个 for/fold
循环,它将为每组值生成的测试用例收集到一个平面列表中。
我不明白的是它似乎成功地 运行 所有测试同时也引发异常:
tests->test-suite-action received #<void> in list of tests (#<void> #<void> #<void> #<void> #<void> #<void> #<void> #<void>), which is not a test.
context...:
/usr/share/racket/pkgs/rackunit-lib/rackunit/private/test-suite.rkt:139:7
/usr/share/racket/pkgs/rackunit-lib/rackunit/private/test-suite.rkt:136:2
/usr/share/racket/pkgs/rackunit-lib/rackunit/private/test-suite.rkt:61:0: apply-test-suite
/usr/share/racket/pkgs/rackunit-lib/rackunit/text-ui.rkt:91:0: run-tests
"/write-thru-hash/tests.rkt": [running body]
temp35_0
for-loop
run-module-instance!
/usr/share/racket/pkgs/compiler-lib/compiler/commands/test.rkt:179:16
...
1 1 write-thru-hash/tests.rkt
8 tests passed
rkt-write-thru-hash_tests_1 exited with code 1
我在我的每个测试用例中都放了一个 writeln
,我看到那些在上面用 ...
缩写的地方打印出来的行。所以我知道测试实际上是 运行ning.
(测试也 运行 并且在我将它们与 for/fold
循环相乘并在 test-suite
的主体中构建它们之前工作正常)
我的 tests.rkt
代码如下:
(define test-cases-list
(for/fold ([test-cases (list)])
([db-type (list 'sqlite 'postgres)])
(append test-cases
(list
(test-case/fixture "basic operations" ... )
(test-case/fixture "complex serializable keys and values" ... )
(test-case/fixture "custom table-name" ... )
(test-case/fixture "use initial src-hash" ... )))))
(define db-tests
(make-test-suite "db-tests" test-cases-list))
(我正在使用 fixture
库 https://docs.racket-lang.org/fixture/)
更新:
实际上,我认为我的测试用例中的 writeln
是在定义时打印的……即它们 运行 太早了,因为它们在 test-suite
上下文之外。
我猜每个 test-case
returns #<void>
中的尾部 check
,所以我用测试结果(空白)而不是测试用例本身并将其提供给测试套件,因此出现错误。
但是我不知道如何实际使用 make-test-suite
...?
最终找到了一个简单的方法来做到这一点。
我的问题是试图将我的测试用例的多个变体全部动态生成为一个 test-suite
。我没有找到让它工作的方法,我怀疑我必须编写一个宏。
相反,简单的方法是动态定义多个 test-suite
实例,然后遍历它们的列表以 运行 它们:
(define db-test-suites
(for/list ([db-type (list 'sqlite 'postgres)]
[db-conn-fixture (list sqlite-connection-delete-after-use
postgres-connection)])
(define suite-name (format "db-tests: ~a" db-type))
(test-suite suite-name
(test-case/fixture "basic operations"
#:fixture db-conn-fixture
(define db-conn (fixture-value db-conn-fixture))
...)
(test-case/fixture "complex serializable keys and values"
#:fixture db-conn-fixture
(define db-conn (fixture-value db-conn-fixture))
...))))
(for ([current-test-suite db-test-suites])
(run-tests current-test-suite))
更新:
我也找到了实际使用的方法 make-test-suite
:
(define all-tests (make-test-suite "db-test-suites" db-test-suites))
(run-tests all-tests)
这利用了 test-suite 可以包含其他嵌套 test-suite 的事实。我认为这种形式(单个 run-tests
调用)比上面的形式(for
循环中的多个 run-tests
调用)更好。
我在原始问题中的所有问题都在于尝试 pre-define test-suite
容器之外的一堆 test-case
实例。但是这里我们传递 make-test-suite
一个 test-suite
实例的列表,允许它们中的测试推迟 运行ning 直到我们稍后调用 run-tests
.
我正在尝试动态生成一堆测试用例。
基本上我想运行用不同的值多次相同的测试。也许有更好的方法,如果有请告诉我,我还没有找到。
我发现 make-test-suite
说你可以向它传递 test-case
个实例的列表。
所以我做了一个 for/fold
循环,它将为每组值生成的测试用例收集到一个平面列表中。
我不明白的是它似乎成功地 运行 所有测试同时也引发异常:
tests->test-suite-action received #<void> in list of tests (#<void> #<void> #<void> #<void> #<void> #<void> #<void> #<void>), which is not a test.
context...:
/usr/share/racket/pkgs/rackunit-lib/rackunit/private/test-suite.rkt:139:7
/usr/share/racket/pkgs/rackunit-lib/rackunit/private/test-suite.rkt:136:2
/usr/share/racket/pkgs/rackunit-lib/rackunit/private/test-suite.rkt:61:0: apply-test-suite
/usr/share/racket/pkgs/rackunit-lib/rackunit/text-ui.rkt:91:0: run-tests
"/write-thru-hash/tests.rkt": [running body]
temp35_0
for-loop
run-module-instance!
/usr/share/racket/pkgs/compiler-lib/compiler/commands/test.rkt:179:16
...
1 1 write-thru-hash/tests.rkt
8 tests passed
rkt-write-thru-hash_tests_1 exited with code 1
我在我的每个测试用例中都放了一个 writeln
,我看到那些在上面用 ...
缩写的地方打印出来的行。所以我知道测试实际上是 运行ning.
(测试也 运行 并且在我将它们与 for/fold
循环相乘并在 test-suite
的主体中构建它们之前工作正常)
我的 tests.rkt
代码如下:
(define test-cases-list
(for/fold ([test-cases (list)])
([db-type (list 'sqlite 'postgres)])
(append test-cases
(list
(test-case/fixture "basic operations" ... )
(test-case/fixture "complex serializable keys and values" ... )
(test-case/fixture "custom table-name" ... )
(test-case/fixture "use initial src-hash" ... )))))
(define db-tests
(make-test-suite "db-tests" test-cases-list))
(我正在使用 fixture
库 https://docs.racket-lang.org/fixture/)
更新:
实际上,我认为我的测试用例中的 writeln
是在定义时打印的……即它们 运行 太早了,因为它们在 test-suite
上下文之外。
我猜每个 test-case
returns #<void>
中的尾部 check
,所以我用测试结果(空白)而不是测试用例本身并将其提供给测试套件,因此出现错误。
但是我不知道如何实际使用 make-test-suite
...?
最终找到了一个简单的方法来做到这一点。
我的问题是试图将我的测试用例的多个变体全部动态生成为一个 test-suite
。我没有找到让它工作的方法,我怀疑我必须编写一个宏。
相反,简单的方法是动态定义多个 test-suite
实例,然后遍历它们的列表以 运行 它们:
(define db-test-suites
(for/list ([db-type (list 'sqlite 'postgres)]
[db-conn-fixture (list sqlite-connection-delete-after-use
postgres-connection)])
(define suite-name (format "db-tests: ~a" db-type))
(test-suite suite-name
(test-case/fixture "basic operations"
#:fixture db-conn-fixture
(define db-conn (fixture-value db-conn-fixture))
...)
(test-case/fixture "complex serializable keys and values"
#:fixture db-conn-fixture
(define db-conn (fixture-value db-conn-fixture))
...))))
(for ([current-test-suite db-test-suites])
(run-tests current-test-suite))
更新:
我也找到了实际使用的方法 make-test-suite
:
(define all-tests (make-test-suite "db-test-suites" db-test-suites))
(run-tests all-tests)
这利用了 test-suite 可以包含其他嵌套 test-suite 的事实。我认为这种形式(单个 run-tests
调用)比上面的形式(for
循环中的多个 run-tests
调用)更好。
我在原始问题中的所有问题都在于尝试 pre-define test-suite
容器之外的一堆 test-case
实例。但是这里我们传递 make-test-suite
一个 test-suite
实例的列表,允许它们中的测试推迟 运行ning 直到我们稍后调用 run-tests
.