leancheck: Cholesterol-free property-based testing

[ bsd3, library, testing ] [ Propose Tags ]

LeanCheck is a simple enumerative property-based testing library.

It works by producing *tiers* of test values, which are essentially (possibly infinite) lists of finite lists of same-and-increasingly-sized values.

LeanCheck has "lean" core with only 180 lines of Haskell code but provides a selection of utilitites for property testing: test types (Nat, Nat<1-7>, Word<1-4>, Int<1-4>); test operators (==>, ===, &&&, |||); type binding operators.

LeanCheck API is likely to change in the near future.


[Skip to Readme]
Versions [faq] 0.3.0, 0.4.0, 0.4.1, 0.5.0, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.6.4, 0.6.5, 0.6.6, 0.6.7, 0.7.0, 0.7.1, 0.7.2, 0.7.3, 0.7.4, 0.7.5, 0.7.6, 0.7.7, 0.8.0, 0.9.0, 0.9.1
Dependencies base (==4.*), template-haskell (>=2.7 && <2.11) [details]
License BSD-3-Clause
Author Rudy Matela <rudy@matela.com.br>
Maintainer Rudy Matela <rudy@matela.com.br>
Revised Revision 1 made by HerbertValerioRiedel at Wed Jul 19 11:39:26 UTC 2017
Category Testing
Home page https://github.com/rudymatela/leancheck#readme
Source repo head: git clone https://github.com/rudymatela/leancheck
this: git clone https://github.com/rudymatela/leancheck(tag v0.3.0)
Uploaded by rudymatela at Thu Apr 7 13:18:13 UTC 2016
Distributions LTSHaskell:0.8.0, NixOS:0.9.1, Stackage:0.9.1
Downloads 5317 total (184 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2016-04-07 [all 1 reports]

Modules

[Index]

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

For package maintainers and hackage trustees


Readme for leancheck-0.3.0

[back to package description]

LeanCheck

The API is likely to change in the near future

LeanCheck is a simple enumerative property-based testing library. It works by producing tiers of test values, which are essentially (possibly infinite) lists of finite lists of same-and-increasingly-sized values. It is similar to Feat in that regard.

In this README, lines ending with -- > indicate expected return values.

Checking if properties are True

To check if properties are True, just use the function holds :: Testable a => Int -> a -> Bool. It takes two arguments: the number of values to test and a property (function returning Bool), then, it returns a boolean indicating whether the property holds. See (ghci):

import Test.Check
import Data.List
holds 100 $ \xs -> sort (sort xs) == sort (xs::[Int])  -- > True
holds 100 $ \xs -> [] `union` xs == (xs::[Int])        -- > False

Finding counter examples

To find counter examples to properties, you can use the function counterExample :: Testable a => Int -> a -> Maybe [String]. It takes two arguments: the number of values to test and a property (function returning Bool). Then, it returns Nothing if no results are found or Just a list of Strings representing the offending arguments to the property. See (ghci):

import Test.Check
import Data.List

counterExample 100 $ \xs -> sort (sort xs) == sort (xs::[Int])
-- > Nothing

counterExample 100 $ \xs -> [] `union` xs == (xs::[Int])
-- > Just ["[0,0]"]

counterExample 100 $ \xs ys -> xs `union` ys == ys `union` (xs::[Int])
-- > Just ["[]","[0,0]"]

Checking properties like in SmallCheck/QuickCheck

To "check" properties like in SmallCheck and QuickCheck automatically printing results on standard output, you can use the function check :: Testable a => a -> IO ().

import Test.Check
import Data.List

check $ \xs -> sort (sort xs) == sort (xs::[Int])
-- > OK, passed 200 tests.

check $ \xs ys -> xs `union` ys == ys `union` (xs::[Int])
-- > Failed! Falsifiable (after 4 tests):
-- > [] [0,0]

The function check tests for a maximum of 200 tests. To check for a maximum of n tests, use checkFor n. To get a boolean result wrapped in IO, use checkResult or checkResultFor. There is no "quiet" option, just use holds or counterExample in that case.

Testing for custom types

LeanCheck works on properties with Listable argument types. Custom Listable instances are created similarly to SmallCheck:

data MyType = MyConsA
            | MyConsB Int
            | MyConsC Int Char
            | MyConsD String

instance Listable MyType where
  tiers = cons0 MyConsA
       \/ cons1 MyConsB
       \/ cons2 MyConsC
       \/ cons1 MyConsD

The tiers function return a potentially infinite list of finite sub-lists (tiers). Each tier has values of increasing size.

tiers :: Listable a => [[a]]

For convenience, there is also the function list, which returns an infinite list of values of the bound type:

list :: Listable a => [a]

So, for example:

take 5 (list :: [(Int,Int)]) -- > [(0,0),(0,1),(1,0),(0,-1),(1,1)]

The list function can be used to debug your custom instances.

More information / extra functions

Listable class instances are more customizable than what is described here: check source comments or haddock documentation for details.

Building / Installing

To build:

$ cabal build

To install:

$ cabal install

To reference in a cabal sandbox:

$ cabal sandbox add-source ../path/to/leancheck

To use the files directly in your project:

$ cp -r Test ../path/to/your-project

LeanCheck was tested on GHC 7.10, GHC 7.8, GHC 7.6 and GHC 7.4. This library does not use any fancy extensions: if it does not work on previous GHC versions, probably only minor changes are needed. It optionally depends on Template Haskell (for automatic derivation of Listable instances).