How to use cabal with bash tests

In my project, I wrote some unit tests like bash scripts. There really was no sensible way to write tests in Haskell.

I would like these scripts to run when entering cabal test . How to do it?

+5
source share
2 answers

This module allows you to run all .sh scripts in a specific subdirectory as a test. In addition, it uses the test-framework package, so if you want, you can run the test like:

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

And you can get junit style XML from tests. This parameter is currently being tested in my project to test the properties of Kebal . Security Code:

 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) 

I use this with this sentence in a .cabal file:

 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 

Note that although I put the .sh tags and the test module in the same directory (called test ), there is no reason for this.

+3
source

First you need to add the test package to your cabal file. To do this, you will use the exitcode-stdio test exitcode-stdio , which will look something like this:

 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 above test suite was taken from Cabal documentation for test suites.

Then in your test-foo.hs you run a bash script and die with an exception for a non-zero exit code. You can do this using 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 () 

Then you can run the above test using cabal test and it will report a testing error if your shell program has a non-zero exit code.

+1
source

All Articles