Haskell单元测试 [英] Haskell unit testing

查看:95
本文介绍了Haskell单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是哈斯克尔的新手,正在从事单元测试工作,但我发现生态系统非常混乱。我对HTF和HUnit之间的关系感到困惑。在一些例子中,我看到你设置了测试用例,将它们导出到一个测试列表中,然后用 runTestsTT (如这个HUnit示例)。在其他例子中,你创建了一个绑定到cabal文件中的测试运行器,它使用了一些预处理器的魔法来找到你的测试,就像这个 github.com/skogsbaer/HTF/blob/master/sample/TestMain.hsrel =noreferrer> git示例。此外,似乎HTF测试需要前缀 test _ 或者它们不运行?我很难找到任何文档,我只注意到每个人都有的模式。



无论如何,有人可以帮我解决这个问题吗?什么被认为是Haskell做事的标准方式?什么是最佳实践?什么是最容易设置和维护?

解决方案

一般来说,任何重要的Haskell项目都可以使用 Cabal 。这需要关心构建,分发,文档(在haddock的帮助下)和测试。

标准方法是将测试放在 test 目录,然后在 .cabal 文件中设置一个测试套件。详细信息请参阅用户手册。以下是我的一个项目的测试套件的样子:

  Test-Suite测试 - 旋律
类型:exitcode- stdio-1.0
main-is:Main.hs
hs-source-dirs:test
build-depends:base> = 4.6&& < 4.7,
test-framework,
test-framework-hunit,
HUnit,
containers == 0.5。*

然后在文件 test / Main.hs

  import Test.HUnit 
import Test.Framework
import Test.Framework.Providers.HUnit
import Data.Monoid
import Control.Monad
import Utils

pushTest :: Assertion
pushTest = [NumLit 1] ^? push(NumLit 1)

pushPopTest :: Assertion
pushPopTest = [] ^? (push(NumLit 0)>> void pop)

main :: IO()
main = defaultMainWithOpts
[testCasepushpushTest
,testCase push-poppushPopTest]
mempty

其中 Utils 通过 HUnit 定义了一些更好的接口。



对于轻量级测试,我强烈建议您使用 QuickCheck 一>。它可以让你编写简短的属性,并通过一系列随机输入来测试它们。例如:

   -  Tests.hs 
import Test.QuickCheck

prop_reverseReverse: :[Int] - > Bool
prop_reverseReverse xs = reverse(reverse xs)== xs

然后

  $ ghci Tests.hs 
> import Test.QuickCheck
> quickCheck prop_reverseReverse
....通过测试(100/100)


I'm new to haskell and working on unit testing, however I find the ecosystem to be very confusing. I'm confused as to the relationship between HTF and HUnit.

In some examples I see you set up test cases, export them in an tests list, and then run in ghci with runTestsTT (like this HUnit example).

In other examples, you create a test runner tied into the cabal file that uses some preprocessor magic to find your tests like in this git example. Also it seems that HTF tests need to be prefixed with test_ or they aren't run? I had a hard time finding any documentation on that, I just noticed the pattern that everyone had.

Anyways, can someone help sort this out for me? What is considered the standard way of doing things in Haskell? What are the best practices? What is the easiest to set up and maintain?

解决方案

Generally, any significant Haskell project is run with Cabal. This takes care of building, distribution, documentation (with the help of haddock), and testing.

The standard approach is to put your tests in the test directory and then set up a test suite in your .cabal file. This is detailed in the user manual. Here's what the test suite for one of my projects looks like

Test-Suite test-melody
  type:               exitcode-stdio-1.0
  main-is:            Main.hs
  hs-source-dirs:     test
  build-depends:      base >=4.6 && <4.7,
                      test-framework,
                      test-framework-hunit,
                      HUnit,
                      containers == 0.5.*

Then in the file test/Main.hs

import Test.HUnit
import Test.Framework
import Test.Framework.Providers.HUnit
import Data.Monoid
import Control.Monad
import Utils

pushTest :: Assertion
pushTest = [NumLit 1] ^? push (NumLit 1)

pushPopTest :: Assertion
pushPopTest = [] ^? (push (NumLit 0) >> void pop)

main :: IO ()
main = defaultMainWithOpts
       [testCase "push" pushTest
       ,testCase "push-pop" pushPopTest]
       mempty

Where Utils defines some nicer interfaces over HUnit.

For lighter-weight testing, I strongly recommend you use QuickCheck. It lets you write short properties and test them over a series of random inputs. For example:

 -- Tests.hs
 import Test.QuickCheck

 prop_reverseReverse :: [Int] -> Bool
 prop_reverseReverse xs = reverse (reverse xs) == xs

And then

 $ ghci Tests.hs
 > import Test.QuickCheck
 > quickCheck prop_reverseReverse
 .... Passed Tests (100/100)

这篇关于Haskell单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆