Search code examples
haskelliomonadshunit

HUnit testing with file dependent tests


I have a lexer, and wish to test it against a set of known good test cases. These are held in a subdirectory ./test_src/ , and each has an extension testname.txt

What i'd like to do is get the paths to all relevant test cases:

getTestFiles :: IO [FilePath]
find always (extension ==? ".txt") "/path/to/test_src/"

and create a HUnit TestList containing HUnit TestCases each with an assertion created via a function along the lines of

testMyLexer :: IO FilePath -> Assertion

something along the lines of

myTest :: [IO FilePath] -> Test
myTest = TestList $ fmap TestCase $ fmap testMyLexer 

where I seem to be failng in my approach is that this seems to first require the follwoing function, and then mapping over its result:

unableToDoThis :: IO [FilePath] -> [IO FilePath]

I've a strong suspicion the approach I'm following is impossible, as it seems to require escaping the IO Monad, so what I'm asking is:

  1. is this approach viable, if so what am I missing?
  2. if not, how would you go about solving this problem? It must be pretty common to avoid hard coding in all test cases

Solution

  • Usually if you get wrapped IO a values in arguments then you're probably doing something wrong. Both testMyLexer and myTest can be pure, so instead of

    testMyLexer :: IO FilePath -> Assertion
    myTest :: [IO FilePath] -> Test
    

    do

    testMyLexer :: FilePath -> Assertion
    myTest :: [FilePath] -> Test
    

    Then it's just a matter of using bind from getTestFiles to extract your [FilePath]:

    do
        files <- getTestFiles
        runTestTT $ myTest files