Check Expects
Simple testing in Haskell. Usable on repl.it.
This page explains how to write check-expect
in Haskell in a basic
way that can be used on repl.it (or anywhere). This method works for
small numbers of tests. Hopefully it work well enough for now.
- Write out tests in a list so each gives True when it passes.
- Define a testing main function
test_main
. - Run the
test_main
yourself.
If you have your own computer, you can learn to use the HUnit testing system.
Example of Testing
This program is supposed to give True if every 5 is followed by a 6. It has a bug in it which we can uncover by testing.
-- Is every five followed immediately by a six?
fiveSix :: [Integer] -> Bool
fiveSix [] = True
fiveSix (5:6:xs) = fiveSix xs
fiveSix (5:ys) = False
fiveSix (a:b:xs) = fiveSix xs
fiveSix (a:xs) = fiveSix xs
Testing should make sure that the basic situation works, then check the “edge” cases, usually involving the start and end of the list.
- Does it work in basic cases?
- Does it work when there is a 5,6 at the start?
- Does it work when there is a 5,6 at the end?
- What if a 5 by itself is at the start?
- What if a 5 by itself is at the end?
test56 = [ True == fiveSix [5,6,5,6,5,6]
,True == fiveSix [1,2,3,4,5,6,7,8]
,False == fiveSix [8,7,6,5,4,3,2,1]
,True == fiveSix [4,6,7,8] -- end basic
,True == fiveSix [5,6,1,2,4]
,True == fiveSix [1,2,4,5,6]
,False == fiveSix [5,1,2,4]
,False == fiveSix [1,2,4,5]
]
The testing function:
testMain :: IO()
testMain = do
putStr "All tests passed? "
putStrLn $ case (and test56) of True -> "YES"; False -> "NO";
putStrLn "Results:"
print $ map show test56
You will see that this method has a lot of repetition. You could make functions that would handle the repetition for you. That is one of the things the HUnit package would do.