hypothesis equivalent of quickcheck frequency generator?

  • Last Update :
  • Techknowledgy :

The Haskell tests make use of a helper function which looks like this:

mkIndent ' :: String -> Int -> Gen String
mkIndent ' val size = concat <$> sequence [indent, sym, trailing]
where
whitespace_char = elements " \t"
trailing = listOf whitespace_char
indent = frequency[(5, vectorOf size whitespace_char), (1, listOf whitespace_char)]
sym =
   return val

What I have currently is:

from hypothesis
import strategies as st

@st.composite
def make_indent_(draw, val, size):
   ""
"
Indent `val`
by `size`
using either space or tab.
Will sometimes randomly ignore `size`
param.
""
"
whitespace_char = st.text(' \t', min_size = 1, max_size = 1)
trailing = draw(st.text(draw(whitespace_char)))
indent = draw(st.one_of(
   st.text(draw(whitespace_char), min_size = size, max_size = size),
   st.text(draw(whitespace_char)),
))
return ''.join([indent, val, trailing])

Suggestion : 2

To start using QuickCheck, write down your property as a function returning Bool. For example, to check that reversing a list twice gives back the same list you can write:,Should we replay a previous test? Note: saving a seed from one version of QuickCheck and replaying it in another is not supported. If you want to store a test case permanently you should save the test case itself.,replay :: Maybe (QCGen, Int)Should we replay a previous test? Note: saving a seed from one version of QuickCheck and replaying it in another is not supported. If you want to store a test case permanently you should save the test case itself.,Test all properties in the current module, using a custom quickCheck function. The same caveats as with quickCheckAll apply.

To start using QuickCheck, write down your property as a function returning Bool. For example, to check that reversing a list twice gives back the same list you can write:

import Test.QuickCheck

prop_reverse::[Int] - > Bool
prop_reverse xs = reverse(reverse xs) == xs

You can then use QuickCheck to test prop_reverse on 100 random lists:

>>> quickCheck prop_reverse
++ + OK, passed 100 tests.

To run more tests you can use the withMaxSuccess combinator:

>>> quickCheck(withMaxSuccess 10000 prop_reverse)
   ++ + OK, passed 10000 tests.

To use quickCheckAll, add a definition to your module along the lines of

return []
runTests = $quickCheckAll

For example, suppose we have the following implementation of binary trees:

data Tree a = Nil | Branch a(Tree a)(Tree a)

We can then define shrink as follows:

shrink Nil = []
shrink(Branch x l r) =
   --shrink Branch to Nil[Nil]++
   --shrink to subterms[l, r]++
   --recursively shrink subterms[Branch x ' l'
      r ' | (x', l ', r') < -shrink(x, l, r)]

There is a fair bit of boilerplate in the code above. We can avoid it with the help of some generic functions. The function genericShrink tries shrinking a term to all of its subterms and, failing that, recursively shrinks the subterms. Using it, we can define shrink as:

shrink x = shrinkToNil x++genericShrink x
where
shrinkToNil Nil = []
shrinkToNil(Branch _ l r) = [Nil]

Map a shrink function to another domain. This is handy if your data type has special invariants, but is almost isomorphic to some other type.

shrinkOrderedList::(Ord a, Arbitrary a) => [a] - > [
   [a]
]
shrinkOrderedList = shrinkMap sort id

shrinkSet::(Ord a, Arbitrary a) => Set a - > Set[a]
shrinkSet = shrinkMap fromList toList

For example, listOf, which uses the size parameter as an upper bound on length of lists it generates, can be defined like this:

listOf::Gen a - > Gen[a]
listOf gen = sized $\ n - >
   do k < -choose(0, n)
   vectorOf k gen

For example, listOf, which uses the size parameter as an upper bound on length of lists it generates, can be defined like this:

listOf::Gen a - > Gen[a]
listOf gen = do
      n < -getSize
   k < -choose(0, n)
vectorOf k gen

Suggestion : 3

It then invoked the function on 100 random integers, ensuring that each invocation satisfied the test.,This post gently introduces QuickCheck to test number-theoretic conjectures, including the falsificaton of a conjecture about primes from antiquity that was once open for millenia.,We can encode the notProduct relation (which says than some number is not the product of two others) to hijack QuickCheck for (rather inefficient) prime factorization:,In this generator, the monadic do notation allows the chosen key to be inspected and used in the generation of the subtrees.

After importing Test.QuickCheck, it’s a one-liner:

> quickCheck(\n - > even(n) == > odd(n + 1))
   ++ + OK, passed 100 tests.

First, we need to encode isPrime :: Integer -> Bool:

m `divides`
n = n `mod`
m == 0

isPrime::Integer - > Bool
isPrime n | n <= 1 = False
isPrime 2 = True
isPrime n = not $ any(`divides`
   n)[2..n - 1]

And, then we can ask QuickCheck:

> quickCheck(\n - > isPrime n == > isPrime(2 ^ n - 1)) **
   * Failed!Falsifiable(after 14 tests):
   11

And, we can test it with QuickCheck:

> quickCheck(collatz)[non - termination][ctrl - c] **
   * Failed!Exception: 'user interrupt'(after 1 test):
   0

We need to insert a guard to prevent QuickCheck from diverging:

> quickCheck(\n - > n > 0 == > collatz(n))
   ++ + OK, passed 100 tests.