2015-07-03 8 views
5

Für mein Projekt habe ich einige Komponententests als Bash-Skripte geschrieben. Es gab wirklich keinen vernünftigen Weg, die Tests in Haskell zu schreiben.Wie man cabal mit Bash-Tests verwendet

Ich möchte diese Skripts ausführen, wenn ich cabal test eintippe. Wie mache ich das möglich?

Antwort

1

Zuerst müssen Sie eine Test-Suite zu Ihrer Cabal-Datei hinzufügen. Dazu werden Sie die exitcode-stdio Test-Suite verwenden, die so etwas wie folgt aussehen:

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 

Das obige Beispiel Testsuite von the Cabal documentation for test suites

Dann in Ihrer test-foo.hs Datei gemacht würden Sie die Bash-Skript ausführen und sterben mit einer Ausnahme für einen Nicht-Null-Exit-Code. Sie können dies System.Process mit tun:

-- 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() 

Dann können Sie den obigen Test mit cabal test laufen und es wird einen Testfehler melden, wenn Ihr Shell-Programm einen von Null verschiedenen Exit-Code hat.

+0

Ist es nicht nur in der Cabal-Konfiguration möglich? Ich habe ungefähr 20 Skripte, die ich ausführen möchte, und ich möchte keine leeren Haskell-Programme für jede von ihnen erstellen. Meine derzeitige Lösung, ein Makefile zu verwenden, wäre einfacher. –

+0

Sie können alle innerhalb desselben Haskell-Programms ausführen. Sie müssen kein separates Haskell-Programm für jedes Skript erstellen. –

+0

Wahr, aber wenn ich dann "cabal test" benutze, weiß ich bei fehlgeschlagenem Test nicht, welcher fehlgeschlagen ist. Es wird mir nur sagen, dass eines der Bash-Skripte fehlgeschlagen ist. –

3

Mit diesem Modul können Sie alle .sh Skripte in einem bestimmten Unterverzeichnis als Test ausführen. Darüber hinaus ist diese verwendet das test-framework Paket so, dass, wenn Sie möchten, können Sie den Test als laufen:

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

Und Sie können dann JUnit-Stil XML aus den Tests erhalten. Dies ist derzeit in my project for testing cabal things eingecheckt. Der Testcode:

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) 

Ich benutze diese mit dieser Klausel in meiner .cabal Datei:

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 

Beachten Sie, dass wenn ich die .sh Tests und das Testmodul im gleichen Verzeichnis platziert (genannt test), Es gibt keinen Grund dazu.

Verwandte Themen