0

背景

使用堆栈及其预设文件Spec.hs,据我所知,您需要导入以下测试框架模块才能执行正确的测试:

import qualified Test.Framework as TF
import qualified Test.Framework.Providers.HUnit as FHU
import qualified Test.Framework.Providers.QuickCheck2 as QC2
import qualified Test.HUnit as HU
import qualified Test.QuickCheck as QC

因此,您还需要将添加依赖项添加到package.yaml文件中,如下所示:

tests:
  XYZ-test:
    main:                Spec.hs
    source-dirs:         test
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - Test4
    - test-framework
    - test-framework-hunit
    - test-framework-quickcheck2
    - HUnit
    - QuickCheck

如果您将主题导入测试(调用它MyModule)并在该模块中实现测试用例Spec.hs,那么您无法测试模块内部使用的功能(MyModule)。

要测试内部功能,您可以在模块 ( MyModule) 中实现测试并导出测试。

module MyModule
    (
        ...
        testCases, -- exported test cases
        -- fun1 -- internal function not exported
    ) where

...

import qualified Test.Framework as TF
import qualified Test.Framework.Providers.HUnit as FHU
import qualified Test.HUnit as HU

fun1 :: [Bool] -> Integer -- internal function not exported
fun1 ...

testCases =
    (FHU.testCase "MyModule.fun1 #1" ((fun1 []) HU.@?= 0)) : 
    (FHU.testCase "MyModule.fun1 #2" ((fun1 [True]) HU.@?= 0)) : 
    (FHU.testCase "MyModule.fun1 #2" ((fun1 [True, True]) HU.@?= 2)) : 
    []

但是接下来你还需要导入测试框架(至少是Test.Framework、Test.Framework.Providers.HUnit和Test.HUnit),还需要在( MyModule)的库中添加额外的依赖。因此,package.yaml 看起来像这样:

...
dependencies:
- ...
- test-framework
- test-framework-hunit
- HUnit

library:
  source-dirs: src
...

问题

是否有更精益的方法来导出模块的单元测试MyModule

4

1 回答 1

0

添加数据类型以包装每个测试用例的绑定。理想情况下,在一个模块(例如TestCaseWrap)中将其重用于具有要测试的内部功能的其他模块。

{-| wraps a test case

* prefix: tcw, TCW
* for an assertion
  * to hold/evaluate the test case name
  * to hold/evaluate the actual value of test case
  * to hold/evaluate the expected value of test case
-}
data TestCaseWrap a = 
    TestAssertion {
        -- | name of the test case, needed to reference and find the test case if failed
        rsName :: String, 
        -- | function and actual value evaluated by test case, respectively
        rxActual :: a, 
        -- | expected value evaluated by test case, respectively
        rxExpected :: a }

注意:数据结构TestCaseWrap支持断言,并且可以扩展用于概率快速测试。

在模块MyModule导入TestCaseWrap中定义数据类型TestCaseWrap。用所有测试用例(例如testCasesWrap)填充一个数组。

module MyModule
    (
        ...
        lTestCasesWrap 
    ) where

import qualified TestCaseWrap as TCW

...

fun1 :: [Bool] -> Integer
fun1 ...

testCasesWrap :: [TCW.TestCaseWrap Integer]
testCasesWrap =
    (TCW.TestAssertion "MyModule.fun1 #1" (fun1 []) 0) :
    (TCW.TestAssertion "MyModule.fun1 #2" (fun1 [True]) 0) : 
    (TCW.TestAssertion "MyModule.fun1 #3" (fun1 [True, True]) 2) : 
    []

实现一个函数将包装的测试信息转换为Test. 同样,理想情况下,在一个模块中(例如 TestCaseUnwrap)。

module TestCaseUnwrap
    (
        testCaseFromTestCaseWrap, 
        testCaseFromTestCaseWrapList
    ) where

import qualified TestCaseWrap as TCW

import qualified Test.Framework as TF
import qualified Test.Framework.Providers.HUnit as FHU
import qualified Test.HUnit as HU

testCaseFromTestCaseWrap :: (Eq a, Show a) => (TCW.TestCaseWrap a) -> TF.Test
testCaseFromTestCaseWrap (TCW.TestAssertion sName xActual xExpected) = FHU.testCase sName (xActual HU.@?= xExpected)

testCaseFromTestCaseWrapList :: (Eq a, Show a) => [TCW.TestCaseWrap a] -> [TF.Test]
testCaseFromTestCaseWrapList ltcwA = fmap testCaseFromTestCaseWrap ltcwA

像这样实现 Spec.hs:

import qualified Test.Framework as TF
import qualified Test.Framework.Providers.HUnit as FHU
import qualified Test.Framework.Providers.QuickCheck2 as QC2
import qualified Test.HUnit as HU
import qualified Test.QuickCheck as QC

import qualified MyModule
import qualified TestCaseUnwrap as TCU

main :: IO ()
main = 
    TF.defaultMainWithOpts
        (
            (TCU.testCaseFromTestCaseWrapList  MyModule.testCasesWrap) ++ 
            [
                ... -- other tests
            ]
        )
        mempty

... -- other tests

...它会像这样执行:

XYZ> test (suite: XYZ-test)

MyModule.fun1  #1: [OK]
MyModule.fun1  #2: [OK]
...
... : [OK]
... : [OK]
... : [OK]


         Properties  Test Cases   Total
 Passed  1           71           72
 Failed  0           0            0
 Total   1           71           72

XYZ> Test suite XYZ-test passed
Completed 2 action(s).
于 2021-06-09T11:30:39.383 回答