使用测试创建完整的Haskell堆栈

时间:2012-11-25 03:43:15

标签: haskell cabal hackage test-runner hunit

我是Haskell的新手,我正在尝试构建一个受测试的程序。我决定使用HUnit和Cabal。

从我所看到的一个结构良好的项目看起来如下:

src/
  AppName/
  Appname.hs
testsuite/
  tests/
    AppName/
  TestRunner.hs
AppName.cabal
Setup.hs

对我来说,神秘的部分是TestRunner.hs和AppName.cabal。

testrunner在testuite / tests目录和子目录下运行所有​​测试的样子是什么?它如何与Cabal集成?

另外,如何将hackage依赖项放在AppName.cabal中并从命令行构建它们?

我很难找到一个完整的示例,从头开始构建一个带有测试和依赖项的应用程序。

由于

1 个答案:

答案 0 :(得分:18)

以下是我最近libraries之一使用的.cabal文件的一个片段。

...
Library
  Build-depends:        base >= 4 && < 5, bytestring, directory, filepath, hslogger,
                        SHA, zlib
  Ghc-options:          -Wall
  Exposed-modules:      Ltc.Store

Test-suite reference
  Hs-Source-Dirs:       Test, .
  Main-Is:              ReferenceProps.hs
  Type:                 exitcode-stdio-1.0

  Build-Depends:        base >= 4 && < 5, bytestring, directory, filepath, hslogger,
                        SHA, zlib
  Ghc-Options:          -Wall

  Build-Depends:        test-framework, test-framework-hunit, test-framework-quickcheck2,
                        HUnit, QuickCheck

我们可以看到cabal文件定义了一个库和一个测试套件。该库定义了它导出的模块,它依赖的包,并设置了一些自定义的GHC选项。

我们可以轻松地构建和打包库以便分发:

% cabal configure
% cabal build
% cabal sdist

testsuite看起来很像库:首先,它与库具有相同的依赖关系(请参阅第一个Build-Depends行),然后添加一些额外的测试依赖项(请参阅第二个{{ 1}}行)。这里的测试套件是HUnit和QuickCheck测试的组合,它使用Test-Framework作为跑步者。 测试正确为Build-Depends。这是Test/ReferenceProps.hs类型测试。这意味着如果exitcode-stdio以代码0退出,cabal会说测试通过。否则,它会说测试失败。

testsuite看起来像this(但是,在这里,我们将使用一些简单的列表反转测试):

ReferenceProps

import Data.Monoid import Test.Framework import Test.Framework.Providers.HUnit import Test.Framework.Providers.QuickCheck2 import Test.HUnit import Test.QuickCheck main :: IO () main = defaultMainWithOpts [ testCase "rev" testRev , testProperty "listRevRevId" propListRevRevId ] mempty testRev :: Assertion testRev = reverse [1, 2, 3] @?= [3, 2, 1] propListRevRevId :: [Int] -> Property propListRevRevId xs = not (null xs) ==> reverse (reverse xs) == xs 只是一种安全带。您还可以通过替换maintest-framework设置各种选项。函数mempty是一个HUnit测试,testRev是一个QuickCheck测试;请参阅relevant docs了解如何撰写这些内容。

最后,我们可以运行测试:

propListRevRevId