【问题标题】:Dynamically generating rackunit test-suite: tests pass and also raise exception动态生成 rackunit 测试套件:测试通过并引发异常
【发布时间】:2020-08-09 16:25:19
【问题描述】:

我正在尝试动态生成一堆测试用例。

基本上我想用不同的值多次运行相同的测试。也许有更好的方法可以做到这一点,如果有,请告诉我,我还没有找到。

我找到了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,我看到打印出来的那些行是我在上面用... 缩写的地方。所以我知道测试实际上正在运行。

(在我将它们与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))

(我正在使用fixturehttps://docs.racket-lang.org/fixture/

更新:

实际上,我认为我的测试用例中的 writeln 是在定义时打印的……也就是说,它们运行得太早了,因为它们超出了 test-suite 上下文。

我猜每个test-case 中的尾部check 返回#&lt;void&gt;,所以我用测试结果(空白)而不是测试用例本身填写了一个列表,并将其提供给测试套件,因此错误。

但是我不知道如何实际使用make-test-suite...?

【问题讨论】:

    标签: racket rackunit


    【解决方案1】:

    最终找到了一个简单的方法来做到这一点。

    我的问题是试图将我的测试用例的几种变体都动态生成到一个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)
    

    这利用了一个测试套件可以包含其他嵌套测试套件的事实。我认为这种形式(单个 run-tests 调用)比上面的形式(for 循环中的多个 run-tests 调用)更好。

    我在原始问题中的所有问题都是试图在 test-suite 容器之外预定义一堆 test-case 实例。但在这里我们传递make-test-suite 一个test-suite 实例列表,允许其中的测试延迟运行,直到我们稍后调用run-tests

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 2011-09-05
      • 2019-05-24
      • 1970-01-01
      相关资源
      最近更新 更多