Generators

Generators are the way to tell QuickChex how to forge the data to be tested.

They are very important and the core concept of propery based testing.

In QuickChex the generators are the things that stay in the with: element of the check function invocation.

How to use them

In the QuickChex.Generators module there are some examples of how to use them.

There are some things to understand.

You can call any of the generators in the QuickChex.Generators module inside a with: element, exactly like normal elixir code.

There are some higher order generators like QuickChex.Generators.list_of/1 that accepts another generator as argument. In this case you have to use the generator name as an atom, or a tuple if you want to pass arguments. Here is an example:

check :the_property,
  with: [list_of(:non_neg_integer)] # list of non negative integers

check :another_property,
  with: [list_of({:non_neg_integer, [1,10]})] # list of non negative integers between 1 and 10

Custom generators

The QuickChex.Generators try to fill every needs about generating base data.

When the base generators are not enough, and you need to generates custom data like structs, or really convoluted examples you can always use a closure to generate the data you want.

The function should return a list of values, with the length of the arity of the property you are testing.

for example:

defmodule QuickChex.CustomGeneratorsTest do
  use ExUnit.Case, async: true
  use QuickChex

  property :add_even_numbers, list do
    assert rem(Enum.sum(list), 2) === 0
  end

  check :add_even_numbers,
    with: fn ->
      even_numbers = 0..10
      |> Enum.map(fn _ ->
        1..100
        |> Enum.filter(&(rem(&1, 2) === 0))
        |> Enum.random
      end)
      [even_numbers] # <- the property accept a single variable, list, so we return a list with a single element.
    end
end