Properties
Relevant source files
The following files were used as context for generating this wiki page:- packages/fast-check/src/check/property/Property.ts
- packages/fast-check/src/check/property/AsyncProperty.ts
- packages/fast-check/src/check/property/IRawProperty.ts
- packages/worker/CHANGELOG.md
- website/blog/2025-03-10-whats-new-in-fast-check-4-0-0/index.md
- website/blog/2024-03-04-whats-new-in-fast-check-3-16-0/index.md
- examples/README.md
In fast-check, a "Property" is the central concept of property-based testing. It defines a universal truth or invariant about your code that should hold true for all possible inputs. A property combines input generators (Arbitraries) with a predicate function that performs the test and makes assertions.
The framework provides two main types of properties: synchronous (property) and asynchronous (asyncProperty). These are responsible for generating input values, executing the test logic, and reporting the outcome.
Sources: examples/README.md, packages/fast-check/src/check/property/Property.ts, packages/fast-check/src/check/property/AsyncProperty.ts
Core Architecture
All properties implement the IRawProperty interface, which defines the essential contract for a property. There are two concrete implementations: Property for synchronous tests and AsyncProperty for asynchronous tests.
Sources: packages/fast-check/src/check/property/IRawProperty.ts
IRawProperty<T> Interface
This interface is the foundation for all property types. It ensures that any property can be generated, run, and identified as either synchronous or asynchronous.
| Method | Description |
|---|---|
isAsync(): boolean | Returns true if the property's predicate is asynchronous, false otherwise. |
generate(mrng: Random): Value<T> | Generates a single value for the property using the provided random number generator. |
run(v: T, ...): RunResult | Executes the property's predicate with a generated value v. Returns a RunResult indicating success, failure, or a skip. |
Sources: packages/fast-check/src/check/property/IRawProperty.ts:10-23
The following class diagram illustrates the relationship between the core property interface and its implementations.
Synchronous Property
The Property<T> class handles synchronous predicates. It is created using fc.property(...).
Sources: packages/fast-check/src/check/property/Property.ts
Execution Flow
The run method executes the predicate with a generated value. It wraps the execution in a try...catch block to handle failures. It also manages preconditions and setup/teardown hooks.
The following flowchart shows the logic of the Property.run method.
Asynchronous Property
The AsyncProperty<T> class is designed for properties with asynchronous predicates that return a Promise. It is created using fc.asyncProperty(...).
Sources: packages/fast-check/src/check/property/AsyncProperty.ts
Execution Flow
The run method of AsyncProperty is similar to its synchronous counterpart but operates entirely within a Promise chain. It handles async predicates, beforeEach, and afterEach hooks.
The sequence diagram below illustrates the asynchronous execution flow.
Key Features
Preconditions (fc.pre)
Preconditions allow you to filter out generated values that are not relevant for a specific test. If fc.pre(condition) is called with a false condition, the current test run is skipped, and fast-check will attempt to generate a new value that satisfies the precondition.
Since version 3.16.0, fc.pre also acts as a TypeScript assertion function, which helps refine types within the predicate's scope.
// entries: {value: T}[]
const match = entries.find((e) => e.value === needle);
fc.pre(match !== undefined);
// TypeScript now knows that `match` is of type `{value: T}`
Sources: website/blog/2024-03-04-whats-new-in-fast-check-3-16-0/index.md, packages/worker/CHANGELOG.md
Setup and Teardown Hooks
Properties support beforeEach and afterEach hooks. These are executed before and after each run of the predicate, respectively. This is useful for setting up state before a test and cleaning up resources afterward. The enforcement of these hooks was refined in version 4.0.0.
Sources: website/blog/2025-03-10-whats-new-in-fast-check-4-0-0/index.md, packages/fast-check/src/check/property/Property.ts:25-26, packages/fast-check/src/check/property/AsyncProperty.ts:26-27
Execution in Workers
The @fast-check/worker package allows properties to be executed in isolated worker threads. This provides several advantages:
- Timeout long-running tests: It can stop synchronous code that gets stuck in an infinite loop.
- Isolation: Workers can be respawned on crashes, providing a clean environment for each run. Different isolation levels (
run,file) are available. - Non-serializable data: As of version 0.3.0, workers support generating inputs within the worker, allowing for tests with non-serializable data.
Sources: packages/worker/CHANGELOG.md