[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5. Properties

A predicate is just a boolean function over some type. A property carries some additional data about preconditions and statistics.

 
type 'a pred = 'a → bool                             
type 'a prop                                          
val pred : 'a pred → 'a prop                         
val pred2 : ('a * 'b) pred → 'b → 'a  prop          

This function and operator are the same: they construct conditional properties. Test cases that fail the precondition are not counted.

 
val implies : 'a pred * 'a prop → 'a prop            
val ==> : 'a pred * 'a pred → 'a prop                


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1 Statistical distribution

One problem with random test-case generation is that we don't know for sure what we're getting. QCheck provides a way to observe the distribution of test cases by tagging them based on user-definable criteria. For example, suppose we want to test the ListMergeSort module in the SML/NJ library, by generating random integer lists.

If we generate and pass 100 cases, what does that mean? Sorting a list with fewer than 2 elements is pretty easy, so how many of our 100 cases are that trivial? Also, how many of the lists are already ordered? The following functions are designed to help you answer such questions.

 
val trivial : 'a pred → 'a prop → 'a prop           
val classify : 'a pred → string → 'a prop → 'a prop
val classify' : ('a → string option) → 'a prop →   
                'a prop 

Here are some examples of how they work.

 
fun fewer_than n L = length L < n

val sort_ok = ListMergeSort.sorted op> o
              ListMergeSort.sort op>

val sort_test = trivial (fewer_than 2)
               (classify (ListMergeSort.sorted op>) "pre-sorted"
               (pred sort_ok))

checkGen (Gen.list (Gen.flip'(1,9)) Gen.Int.int, NONE)
         ("ListMergeSort", sort_test)

Now the test result, if passing, will be accompanied with some statistics on the distribution of the specified properties.

 
› ListMergeSort..........ok      (100 passed)         33% pre-sorted
›                                                     28% trivial

The functions classify and trivial are specializations of the more general classify' (prime), with which we can provide a function that returns the tag. To see the complete distribution of list lengths, try this:

 
fun sizeTag n = 
    "length "^ StringCvt.padLeft #" " 3 (Int.toString n)

val sort_test = classify' (SOME o sizeTag o length) (pred sort_ok)
checkGen (Gen.list (Gen.flip'(1,9)) Gen.Int.int, NONE)
         ("ListMergeSort", sort_test)

› ListMergeSort..........ok      (100 passed)         13% length   0
›                                                      7% length   1
›                                                      6% length   2
›                                                     13% length   3
›                                                      8% length   4
›                                                      6% length   5
›                                                      3% length   6
›                                                      2% length   7
›                                                      5% length   8
›                                                      5% length   9
›                                                      2% length  10
›                                                      5% length  11
›                                                      3% length  12

The list goes on: the maximum length list generated in this run was 43.

 

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2 Results

 
type result = bool option                             
type stats = { tags : StringBag.bag,                  
               count : int }

val test : 'a prop → 'a * stats → result * stats    
val stats : stats                                     
val success : result pred                             
val failure : result pred                             

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Chris League on April, 14 2008 using texi2html 1.78.