Skip to content

Building Custom Generator from Scratch

New to property-based testing? Start with the Walkthrough for a step-by-step guide. Before building a custom generator from scratch, consider combining existing generators with combinators.filter(), .map<U>(), .flatMap<U>(), .pairWith<U>(), or gen::construct often suffice. Build from scratch only when you need generation logic that cannot be expressed by composing these.

 

When to Build from Scratch

Custom generators are useful when:

 

Generator<T> and Arbitrary<T>

Generator<T> and Arbitrary<T> are the standard generator types in cppproptest. Both share the same chainable utility methods (.filter(), .map<U>(), .flatMap<U>(), etc.). Generator<T> is commonly the result of combinators; Arbitrary<T> is the default generator for a type. They are fully chainable—you can use any generator with forAll and chain methods as needed.

 

Building a Custom Generator

A generator in cppproptest is simply a callable with signature (Random&) -> Shrinkable<T>. Simplest way to make a shrinkable is to use make_shrinkable<T>(value) to wrap your value. This makes a shrinkable with no further shrinks. See Shrinking for details on Shrinkable.

You can wrap your callable with Generator<T> to decorate it as a standard generator with same chainable utility methods as built-in generators and Arbitraries:

auto myIntGen = Generator<int>([](Random& rand) {
    int smallInt = rand.getRandomInt8();
    return make_shrinkable<int>(smallInt);
});

// Chain with .filter(), .map(), etc. like any other standard generators
auto evenGen = myIntGen.filter([](const int& value) {
    return value % 2 == 0;
});

 


  • Combinators - .filter(), .map(), .flatMap(), and other utility methods for transforming generators
  • Generators - Built-in generators for primitives and containers
  • Arbitrary - Defining default generators for types used in forAll without explicit generator arguments
  • Shrinking - How Shrinkable and make_shrinkable enable automated simplification of failing inputs
  • Property API - Using custom generators with forAll and property()
  • Walkthrough - Step-by-step guide for creating property tests