【问题标题】:Creating a Full Haskell Stack with Tests使用测试创建完整的 Haskell 堆栈
【发布时间】:2012-11-25 03:43:15
【问题描述】:

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

据我所见,一个结构良好的项目如下所示:

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

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

在 testsuite/tests 目录和子目录下运行所有​​测试的测试运行程序会是什么样子?以及如何与 Cabal 集成?

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

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

谢谢

【问题讨论】:

标签: haskell cabal hackage test-runner hunit


【解决方案1】:

这是我最近用于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

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

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

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

main 只是一个安全带。您还可以通过替换memptytest-framework 设置各种选项。函数testRev是HUnit测试,propListRevRevId是QuickCheck测试;请参阅 relevant docs 了解如何编写这些内容。

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

% cabal configure --enable-tests
% cabal test

【讨论】:

  • 非常感谢,这回答了我的大部分问题,我喜欢你链接到 github 的方式。还有一件事,您将如何在 Test/ 的子目录中运行测试?我不想将所有测试放在一个文件中,如果我创建测试文件时测试自动在 testrunner 中运行,那就太好了。
  • 我能想到两种方法:1)在 cabal 文件中添加更多 Test-Suite 部分(这会很快变得烦人,但如果你只有几个,这可能是最简单的解决方案测试套件),或 2)将您的测试拆分为多个文件,导出每个文件中的测试列表,然后使用单个运行器 concat 测试列表并运行它们。
猜你喜欢
  • 2019-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 2014-01-06
  • 1970-01-01
相关资源
最近更新 更多