如何使用Haskell堆栈项目运行多个测试文件

1ij*_*ijk 16 tdd haskell unit-testing cabal haskell-stack

我想用Stack设置一个现有的Haskell项目.现有项目在test目录下使用多个文件; 这些单独的测试文件默认情况下,Stack(或cabal?)似乎使用单个test/Spec.hs测试文件.如何继续使用此项目的多个文件?

注意:我正在学习Haskell,这个项目接近我从"kata"方法学习.因此,测试是孤立的,一次只关注语言的一个方面.

eps*_*lbe 26

这是一个像这样的目录结构的设置

> tree                                                                                       
.
??? example.cabal
??? app
?   ??? Main.hs
??? ChangeLog.md
??? LICENSE
??? Setup.hs
??? src
?   ??? A
?   ?   ??? C.hs
?   ??? A.hs
?   ??? B.hs
??? stack.yaml
??? tst
    ??? integration
    ?   ??? Spec.hs
    ??? unit
        ??? A
        ?   ??? CSpec.hs
        ??? ASpec.hs
        ??? BSpec.hs
        ??? Spec.hs
Run Code Online (Sandbox Code Playgroud)

您希望集成测试与通常的单元测试分开,并且几个子模块对应于文件src夹中的每个模块

首先,您需要将测试套件添加到您的

example.cabal 文件

name:                example
...
-- copyright:
-- category:
build-type:          Simple
extra-source-files:  ChangeLog.md
cabal-version:       >=1.10

executable testmain
  main-is:       Main.hs
  hs-source-dirs: app
  build-depends: base
               , example

library
  exposed-modules:     A.C,A,B
  -- other-modules:
  -- other-extensions:
  build-depends:       base >=4.9 && <4.10
  hs-source-dirs:      src
  default-language:    Haskell2010

test-suite unit-tests
  type:          exitcode-stdio-1.0
  main-is:       Spec.hs
  hs-source-dirs: tst/unit
  build-depends: base
               , example
               , hspec
               , hspec-discover
               , ...

test-suite integration-tests
  type:          exitcode-stdio-1.0
  main-is:       Spec.hs
  hs-source-dirs: tst/integration
  build-depends: base
               , example
               , hspec
               , ...
Run Code Online (Sandbox Code Playgroud)

把下面的你tst/unit/Spec.hs就从hspec-discover它发现(因此得名)形式的所有模块...Spec.hs,并执行spec从每个这些模块的功能.

tst/unit/Spec.hs

{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
Run Code Online (Sandbox Code Playgroud)

只是这一行

其他测试文件

然后添加在你的单元测试ASpec.hs,和其他人在BSpec.hs,CSpec.hs而你Spec.hs的在tst/integration文件夹中

module ASpec where

import Test.Hspec
import A

spec :: Spec
spec = do
  describe "Prelude.head" $ do
    it "returns the first element of a list" $ do
      head [23 ..] `shouldBe` (23 :: Int)

    it "returns the first element of an *arbitrary* list" $
      property $ \x xs -> head (x:xs) == (x :: Int)

    it "throws an exception if used with an empty list" $ do
      evaluate (head []) `shouldThrow` anyException
Run Code Online (Sandbox Code Playgroud)

然后,您可以编译并运行测试

$> stack test
# now all your tests are executed
$> stack test :unit-tests
# now only the unit tests run
$> stack test :integration-tests
# now only the integration tests run
Run Code Online (Sandbox Code Playgroud)

来源

您可以在https://hspec.github.io上找到所有示例,如果您想了解更多有关hspec样式测试的信息,我想最好从那里开始.对于堆栈 - 转到https://haskellstack.org - 有一些关于测试/基准测试的信息 - 我的意思是运行测试和基准测试.

对于haskell的不同测试风格,请参阅HUnit,QuickCheck,Smallcheck,doctests(如果我忘了一个,我最亲爱的道歉 - 那些也是我经常使用的那些).

  • @DavidWoods 我认为这个警告是最近的,所以在写这个答案时我没有得到它。一种解决方案是您在 cabal-file 的“ghc-options”部分中添加标志“-Wno-missing-home-modules”。 (2认同)