package hegel

  1. Overview
  2. Docs

Module Hegel.StatefulSource

Stateful property-based testing.

Introduction

A stateful test exercises a system through a sequence of randomly chosen actions ("rules") applied to a state. Rules are constructed with Rule.create from a name and a step function that performs one application of the rule, drawing any arguments it needs from the test case and returning the new state. Invariants are 'state -> unit functions evaluated before any step is run and after every successful step.

To run a state machine, call run inside a Hegel test. Examples in this documentation assume open Hegel.

Example: an integer stack.

let push =
  Stateful.Rule.create ~name:"push" ~step:(fun tc stack ->
      let n =
        draw tc (Generators.integers ~min_value:0 ~max_value:100 ())
      in
      n :: stack)

let pop =
  Stateful.Rule.create ~name:"pop" ~step:(fun tc stack ->
      assume tc (not (List.is_empty stack));
      List.tl stack)

let%hegel_test test_integer_stack tc =
  Stateful.run ~init:[] ~rules:[ push; pop ] tc

Submodules

Sourcemodule Pool : sig ... end
Sourcemodule Rule : sig ... end

Running stateful tests

Sourceval run : init:'state -> rules:'state Rule.t list -> ?invariants:('state -> unit) list -> test_case -> unit

Executes a stateful test by repeatedly applying randomly chosen rules to a state threaded from init, checking each of the invariants before the first step and after every successful step. Raises Invalid_argument if rules is empty.