Simple haskell unit testing

Unit TestingHaskell

Unit Testing Problem Overview


I want to go through 99 Haskell Problems, and I want to concentrate on the solution but with testing. If I have the solution to the first problem as a 3 line .hs file,

myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs

What is the minimal amount of code I can add to this so that I can add tests inline and run them with runhaskell?

Unit Testing Solutions


Solution 1 - Unit Testing

QuickCheck (which basicaly generates test inputs for you) is probably the best way to test pure function. And if a function in question has an analog from the standard library you can just test your function using the standard one as a model:

{-# LANGUAGE TemplateHaskell #-}

import Test.QuickCheck
import Test.QuickCheck.All

myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs

-- here we specify that 'myLast' should return exactly the same result
-- as 'last' for any given 'xs'
prop_myLast xs = myLast xs == last xs


return [] -- need this for GHC 7.8
-- quickCheckAll generates test cases for all 'prop_*' properties
main = $(quickCheckAll)

If you run it you'll get:

=== prop_myLast on tmp3.hs:12 ===
*** Failed! Exception: 'tmp3.hs:(7,1)-(8,25): Non-exhaustive patterns in function myLast' (after 1 test):  
[]
False

because your myLast doesn't handle [] case (it should but should probably throw an error like 'last'). But here we can simply adjust our test but specifying that only non-empty strings should be used (using ==> combinator):

prop_myLast xs = length xs > 0 ==> myLast xs == last xs

Which makes all 100 auto-generated test cases to pass for myLast:

=== prop_myLast on tmp3.hs:11 ===
+++ OK, passed 100 tests.
True

PS Another way to specify myLast behavior may be:

prop_myLast2 x xs = myLast (xs++[x]) == x

Or better:

prop_myLast3 x xs = x `notElem` xs ==> myLast (xs++[x]) == x

Solution 2 - Unit Testing

hspec is also a testing framework for Haskell, which is inspired by Ruby RSpec. It integrates with QuickCheck, SmallCheck, and HUnit.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDaniel HuckstepView Question on Stackoverflow
Solution 1 - Unit TestingEd'kaView Answer on Stackoverflow
Solution 2 - Unit TestingstianView Answer on Stackoverflow