如何使用bash测试cabal

时间:2015-07-03 20:34:06

标签: haskell cabal

对于我的项目,我已经编写了一些单元测试作为bash脚本。确实没有合理的方法在Haskell中编写测试。

我想在输入cabal test时运行这些脚本。我该如何做到这一点?

2 个答案:

答案 0 :(得分:3)

此模块允许您运行特定子目录中的所有.sh脚本作为测试。此外,它使用test-framework包,因此如果需要,您可以将测试运行为:

cabal test '--test-option=--jxml=dist/test/$test-suite.xml'

然后,您可以从测试中获取junit样式的XML。目前已在my project for testing cabal things中签入。测试代码:

import Data.List (isSuffixOf)
import Control.Applicative
import Test.Framework (defaultMain, testGroup, Test)
import Test.Framework.Providers.HUnit
import Test.HUnit (assertFailure)
import System.Directory
import System.Exit (ExitCode(..))
import System.Process


main :: IO ()
main = makeTests "test" >>= defaultMain

-- Make a test out of those things which end in ".sh" and are executable
-- Make a testgroup out of directories
makeTests :: FilePath -> IO [Test]
makeTests dir = do
  origDir <- getCurrentDirectory
  contents <- getDirectoryContents dir
  setCurrentDirectory dir
  retval <- mapM fileFunc contents
  setCurrentDirectory origDir
  return $ concat retval
  where
    fileFunc "." = return []
    fileFunc ".." = return []
    fileFunc f | ".sh" `isSuffixOf` f = do
      fullName <- canonicalizePath f
      isExecutable <- executable <$> getPermissions fullName
      let hunitTest = mkTest fullName
      return [testCase f hunitTest | isExecutable]
    fileFunc d = do
      fullName <- canonicalizePath d
      isSearchable <- searchable <$> getPermissions fullName
      if isSearchable
        then do subTests <- makeTests d
                return [testGroup d subTests]
        else return []
    mkTest fullName = do
      execResult <- system fullName
      case execResult of
        ExitSuccess -> return ()
        ExitFailure code -> assertFailure ("Failed with code " ++ show code)

我在.cabal文件中使用此子句:

test-suite BackflipShellTests
  type:                exitcode-stdio-1.0
  main-is:             BackflipShellTests.hs
  hs-source-dirs:      test
  build-depends:       backflip, base, test-framework-hunit,
                       test-framework, directory, process, HUnit
  default-language:    Haskell2010

请注意,虽然我将.sh测试和测试模块放在同一目录(称为test)中,但没有固有的理由这样做。

答案 1 :(得分:1)

首先,您需要在cabal文件中添加测试套件。为此,您将使用exitcode-stdio测试套件,它看起来像这样:

Name:           foo
Version:        1.0
License:        BSD3
Cabal-Version:  >= 1.9.2
Build-Type:     Simple

Test-Suite test-foo
    type:       exitcode-stdio-1.0
    main-is:    test-foo.hs
    build-depends: base

以上示例测试套件取自the Cabal documentation for test suites

然后在你的test-foo.hs文件中运行bash脚本并死掉非零退出代码的异常。您可以使用System.Process

执行此操作
-- test-foo.hs
import System.Exit (ExitSuccess)
import System.Process (system)

main = do
    -- This dies with a pattern match failure if the shell command fails
    ExitSuccess <- system "./myprog"
    return ()

然后,您可以使用cabal test运行上述测试,如果您的shell程序具有非零退出代码,它将报告测试失败。