In class exercise - HUnit and QuickCheck
In this in class exercise, we will practice our skills using the testing
frameworks HUnit and QuickCheck.
Some references you may want to look at
Recall the 4 steps for developing your Unit-tests along with your program.
- Write a type for the function. Make its body undefined
- Make some examples, and express them as HUnit assertions
- Collect all the tests together. By convention we use the name tests
to collect all the Unit-tests in one file together.
- Then fill in the definition until all tests are passed!
Start by cutting and pasting the program skeleton at
the bottom of the page.
For this exercise you will create a Haskell program which
defines several functions. Study the problem description below for
each function, and then perform the 4 Unit-testing steps to defined
your function. Then develop 2 QuickTest properties for each function
to stress your definition with random tests.
- addOne is a list to list function. Its input is a list of Int, and its output
is a list of Int. The output can be obtained from the input by adding 1 to each element.
For example: addOne [2,6,7] --> [3,7,8]. Be sure you create enough Unit tests before
you start coding.
What might be a good property to test for this function using quickCheck?
- addN is a generalization of addOne. It is a list to list function. Its inputs are and Int and a list of Int, and its output
is a list of Int. The output can be obtained from the input by adding the first input to each element of the second input.
For example: addN 3 [2,6,7] --> [5,9,10].
Can you devise a property to test using Quickcheck that uses
both addOne and addN?
- prefixSums returns a list of numbers.
- The number in the first
position of the list is the sum of the prefix of the input with length 1.
- The number in the second
position of the list is the sum of the prefix of the input with length 2.
- The number in the third
position of the list is the sum of the prefix of the input with length 3, etc.
This is best
illustrated with an example. If the input is [2,6,7,5]
- The prefix of the input with length 1 is .
- The prefix of the input with length 2 is [2,6].
- The prefix of the input with length 3 is [2,6,7].
- The prefix of the input with length 4 is [2,6,7,5].
Thus, the result
is [2,2+6, 2+6+7, 2+6+7+5] --> [2,8,15,20].
Hint: the function addN might be useful. Be sure and write this function recursively.
Can you devise a property to check using Quickcheck that relates
the nth and nth+1 elements of the output to
to the nth+1 element of the input?
- take returns a prefix of a list. The first input is the length of the prefix,
and the second input is the list that the prefix is obtained from. Its possible that
the list is not long enough to obtain a prefix of the supplied length. In that case
return the longest possible prefix.
- take 0 [3,4,5] --> 
- take 6 [3,4] --> [3,4]
- take 3 [2,5,6,7,8] --> [2,5,6]
- take 2  --> 
Hint: this function decomposes both its arguments to make recursive calls.
module TestingExerciseSkeleton where
import Test.HUnit -- (Test(TestCase,TestList),assertEqual,runTestTT)
addOne :: [Int] -> [Int]
addOne = undefined
addN:: Int -> [Int] -> [Int]
addN = undefined
prefixSums:: [Int] -> [Int]
prefixSums = undefined
takE:: Int -> [a] -> [a]
takE = undefined
Back to the Daily Record.
Back to the class web-page.