Property
Module Hedgehog.Property
Property testing with OCaml 5 effects for assertions and logging.
Properties are built by combining generators with effectful test bodies. Assertions, logging, and failure are expressed as algebraic effects, handled by the property runner.
Configuration
type verbosity = | Quiet | NormalVerbosity of the live progress output. Normal reports tests, discards and shrinks on stderr as the run proceeds; Quiet prints nothing until the run finishes.
type config = { test_limit : int; discard_limit : int; shrink_limit : int; verbosity : verbosity;}val default_config : configDefaults: 100 tests, 100 discards, 1000 shrinks. Verbosity is taken from the HEDGEHOG_VERBOSITY environment variable (0 for Quiet, 1 for Normal) and defaults to Normal.
Results
type failure = { message : string; location : string option; diff : Diff.t option;}type cover = | NoCover | Covertype label_data = { label_name : string; label_minimum : float; label_annotation : cover;}type log_entry = | Annotation of string | Footnote of string | Label of label_datatype status = | OK | Failed of { failure : failure; log : log_entry list; } | GaveUptype label_info = { name : string; minimum : float; count : int;}type report = { tests : int; discards : int; shrinks : int; status : status; coverage : label_info list; seed : Seed.t; size : int;}Assertion API (performs effects)
val assert_ : bool -> unitAssert that a condition is true.
val (===) : 'a -> 'a -> unitAssert structural equality.
val diff : ('a -> string) -> ('a -> 'b -> bool) -> ('b -> string) -> 'a -> 'b -> unitdiff show_a eq show_b a b asserts eq a b, showing a diff on failure.
val failure : unit -> 'aExplicitly fail the property.
val annotate : string -> unitLog an annotation (shown on failure, before the counterexample).
val footnote : string -> unitLog a footnote (shown on failure, after the counterexample).
Round-trip testing
val tripping : ('a -> string) -> ('b -> string) -> ('a -> 'b) -> ('b -> 'a option) -> 'a -> unittripping show_a show_b encode decode x encodes x with encode, then decodes with decode, and asserts that the round-trip produces Some x. On failure, annotates the original, intermediate, and round-trip values.
val eval_result : ('e -> string) -> ('a, 'e) Stdlib.result -> 'aeval_result show_error r extracts Ok x or fails the property with show_error e when r is Error e.
Coverage / Classification
val cover : float -> string -> bool -> unitcover minimum name condition requires at least minimum% of tests to satisfy condition under the given label name. Example: cover 30.0 "non-empty" (List.length xs > 0)
val classify : string -> bool -> unitclassify name condition records the proportion of tests satisfying condition. Like cover with 0% minimum (informational only).
val label : string -> unitlabel name labels every test run. Like cover 0 name true.
val collect : ('a -> string) -> 'a -> unitcollect to_string x labels using the string representation of x.
Property construction
type propertyval property : ?config:config -> (unit -> unit) Gen.t -> propertyConstruct a property from a generator of test closures.
Example:
let prop_reverse = property Gen.( let* xs = list (Range.linear 0 100) (int (Range.linear 0 1000)) in return (fun () -> assert_ (List.rev (List.rev xs) = xs)))Config builders
val with_tests : int -> property -> propertySet the number of tests to run. Default 100.
val with_shrinks : int -> property -> propertySet the maximum number of shrinks to perform. Default 1000.
val with_discards : int -> property -> propertySet the maximum number of discards before giving up. Default 100.
val with_verbose : property -> propertyEnable live progress reporting to stderr during property checking. This is the default unless HEDGEHOG_VERBOSITY=0 is set.
val with_quiet : property -> propertySuppress live progress reporting for this property.
Runner
val check : property -> boolRun a property and return whether it passed. Prints a report on failure.
val check_report : property -> reportRun a property and return the full report.
val format_report : ?color:bool -> report -> stringFormat a report as a human-readable string. When ~color:true, ANSI escape codes are included for colored output. Defaults to false.
Group runner
type group = { name : string; properties : (string * property) list;}val check_group : group -> boolRun a group of properties sequentially. Prints per-property results and a summary line. Returns true if all properties passed.
val check_sequential : group -> boolEquivalent to check_group.
val check_parallel : ?num_domains:int -> group -> boolRun properties in parallel using a domainslib task pool. num_domains defaults to Domain.recommended_domain_count () - 1. Properties sharing mutable state may interfere with each other.
Recheck
val recheck : int -> Seed.t -> property -> reportRe-run a property at a specific size and seed for reproducing failures.
Internal — used by Stm
type test_result = | TestPassed of log_entry list (* The test passed, with any log entries collected. *) | TestFailed of failure * log_entry list (* The test failed with a failure and any log entries collected. *)The outcome of running a single test closure under the effect handler.
val run_test : (unit -> unit) -> test_resultRun a test closure, capturing effects. Returns pass/fail with log.