当我的测试失败时,为什么我的HUnit测试套件会通过?

oro*_*ome 10 haskell unit-testing hunit

如果我有test/Test.hs

module Main where

import Test.HUnit

test1 :: Test
test1 = TestCase $ assertEqual "Should be one" 1 5

test2 :: Test
test2 = TestCase $ assertEqual "Shold both be zero" 0 0

main :: IO Counts
main = runTestTT $ TestList [test1, test2, test1]
Run Code Online (Sandbox Code Playgroud)

.cabal

test-suite my-test
    type:               exitcode-stdio-1.0
    hs-source-dirs:     test
    main-is:            Test.hs
    build-depends:      base >= 4.8.1.0 && <4.9,
                        HUnit >= 1.3
    default-language:   Haskell2010
Run Code Online (Sandbox Code Playgroud)

我跑了cabal test --show-details='always'然后我得到了

Test suite my-test: RUNNING...
### Failure in: 0
test/Test.hs:6
Should be one
expected: 1
 but got: 5
### Failure in: 2
test/Test.hs:6
Should be one
expected: 1
 but got: 5
Cases: 3  Tried: 3  Errors: 0  Failures: 2
Test suite my-test: PASS
Run Code Online (Sandbox Code Playgroud)

为什么我的测试套件在我出现故障时通过了?同样,如果我cabal sdist没有得到警告我的测试失败了.

dfe*_*uer 5

根据Cabal用户指南

使用该exitcode-stdio-1.0接口的测试套件是可执行文件,可在运行时以非零退出代码指示测试失败。它们可以通过标准的输出和错误通道提供人类可读的日志信息。

您已经定义

main :: IO Counts
main = runTestTT $ TestList [test1, test2, test1]
Run Code Online (Sandbox Code Playgroud)

这将运行测试,打印出测试信息,然后始终成功退出。如果要Cabal知道测试失败,则需要捕获Counts,检查errorsfailures,如果发现异常,则以非零状态退出。

main :: IO ()
main = do
  results <- runTestTT $ TestList [test1, test2, test1]
  if (errors results + failures results == 0)
    then
      exitWith ExitSuccess
    else
      exitWith (ExitFailure 1)
Run Code Online (Sandbox Code Playgroud)

test-framework软件包提供了方便的defaultMain功能来执行此类操作。您可能要考虑这种方法。

您应该注意,该exitcode-stdio-1.0接口被认为是不建议使用的;阴谋集团的维护者建议改用他们更Haskellian的detailed-0.9界面。