Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Generate fake values with full constructor coverage
The idea behind Fake.Cover is that although exhaustive testing is highly exponential, you can cover a large portion of the likely problem cases by exercising all the constructors of a data type and associated fields. This approach only requires a sub-exponential number of cases--far fewer than what you need for the exhaustive approach. The number of test cases needed to ensure that you have full coverage of all the constructors is given by the following relations for product and sum types:
numCases (a, b) = max (numCases a) (numCases b)
numCases (Either a b) = numCases a + numCases b
See the test suite for examples of how many values are generated for different data types.
Documentation
gcover :: (Generic a, GCover ga, ga ~ Rep a) => Coverage a Source #
A generic function that gives you full constructor coverage for a data
type. Using this function as the Cover
instance for a data type avoids
the need to explicitly enumerate values that include coverage of all
constructors.
Coverage is a list of values, implemented here with a newtype around a
list of fake value generators. It's [FGen a]
instead of FGen [a]
because we don't want to have to evaluate the FGen
monad to work with
coverage lists.
Coverage | |
|
A type class that generates a list of values giving full construcor
coverage for data types. You can write your own instances by hand or you
can use the default instance which calls gcover
provided your data type
has a Generic instance.
Nothing
Instances
Cover () Source # | |
Defined in Fake.Cover | |
Cover a => Cover (Maybe a) Source # | |
(Cover a, Cover b) => Cover (Either a b) Source # | |
(Cover a, Cover b) => Cover (a, b) Source # | |
Defined in Fake.Cover | |
(Cover a, Cover b, Cover c) => Cover (a, b, c) Source # | |
Defined in Fake.Cover | |
(Cover a, Cover b, Cover c, Cover d) => Cover (a, b, c, d) Source # | |
Defined in Fake.Cover | |
(Cover a, Cover b, Cover c, Cover d, Cover e) => Cover (a, b, c, d, e) Source # | |
Defined in Fake.Cover | |
(Cover a, Cover b, Cover c, Cover d, Cover e, Cover f) => Cover (a, b, c, d, e, f) Source # | |
Defined in Fake.Cover | |
(Cover a, Cover b, Cover c, Cover d, Cover e, Cover f, Cover g) => Cover (a, b, c, d, e, f, g) Source # | |
Defined in Fake.Cover |
bindCover :: Coverage a -> (a -> FGen b) -> Coverage b Source #
In some situations you don't have the ability to modify a data structure and need to define different Cover instances for different fields that have the same type. In these situations, instead of implementing the gcover logic by hand, you could alternatively use gcover to generate stock coverage values and then go back and replace the necessary fields with more appropriate generators. This bind-like operation provides an easy way to do that.