File: examples/README.md
Examples based on `fast-check`
This directory gathers multiple examples of properties you might come with when using fast-check.
Try online with CodeSandbox.
Teach yourself property based through examples
Examples by category
Following examples show how you could think about properties given algorithms ranging from basic pure functions returning easy to assess outputs to complex state machines.
Simple data structures
101 for property based:
decompPrime- Returns the list of prime factors corresponding to the input valuefibonacci- Returns the item at a given position in the sequence of FibonacciindexOf- Returns the position of the first occurrence ofpatternintextsort- Returns a sorted copy of the input array
Recursive structures
Let's see how to generate recursive inputs using letrec, memo or even none of them:
isSearchTree- Returnstrueif the tree is a binary search tree,falseotherwise
Misc
Various algorithms to have more random examples:
knight- Multi dimensional dichotomy given as a coding exercisemazeGenerator- Maze generatorroman- Convert from and to roman notation for numbers
State machines to user interfaces
Property based testing applied to state machines or user interfaces:
MusicPlayer- Simple music player withplay,pause,addTrackandnext
Race conditions
Property based testing used to detect race conditions in various kind of JavaScript snippets:
AutocompleteField- An autocomplete field written in React providing suggestions as soon as possibleCounter- Increment a counter stored in a DB using compare-and-swapDebouncedAutocomplete- An autocomplete field written in React providing suggestions in a debounced way (uses timers)dependencyTree- Fetch recursively dependencies for a npm packageTodoList- Simple todolist React appUserProfilePage- A simple React component loading user profile on mount
Rules of property based
- Properties do not replace examples, they are just an extra layer of tests
- Properties can be used at any level: unit, integration, end-to-end
Tricks to find properties
- Characteristics independent of the inputs
Examples:
for any floating point number d, Math.floor(d) is an integer
for any integer n, Math.abs(n) โฅ 0
- Characteristics derived from the inputs
Examples:
for any a and b integers the average of a and b is between a and b
for any array โ data, sorted(data) and data contain the same elements
- Restricted set of inputs with useful characteristics
Examples:
for any prime number p, its decomposition into prime factors is itself
for any a, b and c strings the concatenation of a, b and c always contains b
- Characteristics on combination of functions
Examples:
for any file f, unzip(zip(f)) is the original file
for any a, b numbers lcm(a, b) * gcd(a, b) equals a * b
- Comparison with a simpler implementation
File: packages/worker/README.md
`@fast-check/worker`
Provide built-ins to run predicates directly within dedicated workers
Why?
fast-check alone is great but what if it led your code into an infinite and synchronous loop for such inputs? In such case, it would neither be able to shrink the issue, nor to report any for you as the single threaded philosophy at the root of JavaScript will prevent it from anything except waiting for the main thread to come back.
This package tends to provide a way to run easily your properties within dedicated workers automatically spawed by it.
Example
Here are some of the changes you will have to do:
- hoist properties so that they get declared on the root scope
- replace
fc.propertybypropertycoming frompropertyFor() - replace
fc.assertbyassertcoming from@fast-check/workerfor automatic cleaning of the workers as the test ends - transpilation has not been addressed yet but it may probably work
- in theory, if you were only using
propertyForandassertwithout any external framework fortest,itand others, the separation of the property from the assertion would be useless as the check for main thread is fully handled within@fast-check/workeritself so no hoisting needing in such case
import { test } from '@jest/globals';
import fc from 'fast-check';
import { isMainThread } from 'node:worker_threads';
import { assert, propertyFor } from '@fast-check/worker';
const property = propertyFor(new URL(import.meta.url)); // or propertyFor(pathToFileURL(__filename)) in commonjs
const p1 = property(fc.nat(), fc.nat(), (start, end) => {
// starting a possibly infinite loop
for (let i = start; i !== end; ++i) {
// doing stuff...
}
});
if (isMainThread) {
test('should assess p1', async () => {
await assert(p1, { timeout: 1000 });
});
}Refer to the tests defined test/main.spec.ts for a living example of how you can use this package with a test runner such as Jest.
Extra options
The builder of properties propertyFor accepts a second parameter to customize how the workers will behave. By default, workers will be shared across properties. In case you want a more isolation between your runs, you can use:
const property = propertyFor(new URL(import.meta.url), { isolationLevel: 'predicate' });
// Other values:
// - "file": Re-use workers cross properties (default)
// - "property": Re-use workers for each run of the predicate. Not shared across properties!
// - "predicate": One worker per run of the predicateBy default, workers will receive the generated values from their parent thread. In some cases, such sending is made impossible as the generated values include non-serializable pieces. In such cases, you can opt-in to generate the values directly within the workers by using:
const property = propertyFor(new URL(import.meta.url), { randomSource: 'worker' });
// Other values:
// - "main-thread": The main thread will be responsible to generate the random values and send them to the worker thread. It unfortunately cannot send any value that cannot be serialized between threads. (default)
// - "worker": The worker is responsible to generate its own values based on the instructions provided by the main thread. Switching to a worker mode allows to support non-serializable values, unfortunately it drops all shrinking. capabilities.Minimal requirements
- Node โฅ14.18.0(1)(2)(3)
- TypeScript โฅ4.1 (optional)
(1): worker_threads alone would only require Node โฅ10.5.0, but our usage of require(node:*) forces us to request at least Node โฅ14.18.0
(2): this package targets ES2020 specification which is quite well supported (more than 94%) by any Node โฅ14.5.0
(3): this package requires a version of node able to understand package.json#exports, supported by any Node โฅ12.17.0
File: packages/vitest/README.md
`@fast-check/vitest`
Bring the power of property based testing framework fast-check into Vitest.@fast-check/vitest simplifies the integration of fast-check into Vitest.
Getting Started
Install @fast-check/vitest:
npm install --save-dev @fast-check/vitestIn order to work properly, @fast-check/vitest requires vitest to be installed.
Examples
The library comes with two modes, both powered by fast-check:
- One-time random mode โ A lightweight approach that introduces controlled randomness into your tests while keeping runs reproducible.
- Property-based testing mode โ A full-fledged property-based testing approach leveraging the full capabilities of fast-check.
One-time random mode
This mode extends Vitest's default test and it functions, allowing you to introduce controlled randomness into your tests while ensuring failures remain reproducible. This makes it easier to debug flaky tests and avoid irreproducible failures due to randomness.
Unlike property-based testing, this mode does not run tests multiple times or attempt shrinking when failures occur. Instead, it provides a determistic way to introduce randomness when needed.
import { test, fc } from '@fast-check/vitest';
import { expect } from 'vitest';
// You can provide a fixed seed to force a replay by adding this line:
// >> fc.configureGlobal({ seed })
// Eventually you can disable shrinking capabilities with:
// >> fc.configureGlobal({ endOnFailure: false })
// >> // or combine it with the one above if you need both
test('test relying on randomness', ({ g }) => {
// Arrange
const user = {
firstName: g(fc.string),
lastName: g(fc.string),
};
// Act
const displayName = computeDisplayName(user);
// Assert
expect(displayName).toContain(user.firstName);
});
test('test not relying on randomness', () => {
// your test
});Full property-based mode
For more extensive testing, @fast-check/vitest also provides full support for property-based testing. This mode enables exhaustive, randomized testing by generating a variety of inputs and detecting edge cases automatically.
import { test, fc } from '@fast-check/vitest';
// for all a, b, c strings
// b is a substring of a + b + c
test.prop([fc.string(), fc.string(), fc.string()])('should detect the substring', (a, b, c) => {
return (a + b + c).includes(b);
});
// same property but using named values
test.prop({ a: fc.string(), b: fc.string(), c: fc.string() })('should detect the substring', ({ a, b, c }) => {
return (a + b + c).includes(b);
});Please note that the properties accepted by @fast-check/vitest as input can either be synchronous or asynchronous (even just PromiseLike instances).
Seamless integration with Vitest's `beforeEach` / `afterEach`
Vitest's beforeEach and afterEach hooks are natively integrated into predicates. They are called respectively before and after each execution of the predicate. If a predicate runs n times, beforeEach will be called n times before it and afterEach n times after it. The only caveat is that cleanup functions returned by beforeEach on the first predicate execution are deferred until the end of the test, as they are handled by vitest's own teardown mechanism. All other cleanups run between predicate executions as expected.
Advanced
If you want to forward custom parameters to fast-check, test.prop accepts an optional fc.Parameters (more).
@fast-check/vitest also comes with .only, .skip, .todo and .concurrent from vitest. It also accepts more complex ones such as .concurrent.skip.
import { it, test, fc } from '@fast-check/vitest';
test.prop([fc.nat(), fc.nat()], { seed: 4242 })('should replay the test for the seed 4242', (a, b) => {
return a + b === b + a;
});
test.skip.prop([fc.string()])('should be skipped', (text) => {
return text.length === [...text].length;
});
describe('with it', () => {
it.prop([fc.nat(), fc.nat()])('should run too', (a, b) => {
return a + b === b + a;
});
});Minimal requirements
| @fast-check/vitest | vitest | fast-check | Node |
|---|---|---|---|
| 0.4 | ^4.1.0 | ^3.0.0 || ^4.0.0 | โฅ20.19.0(2) |
| 0.3 | ^1 || ^2 || ^3 || ^4 | ^3.0.0 || ^4.0.0 | โฅ20.19.0(2) |
| 0.2 | ^1 || ^2 || ^3 || ^4(1) | ^3.0.0 || ^4.0.0 | โฅ18(3) |
| 0.1 | >=0.28.1 <1.0.0 || ^1 || ^2(4) || ^3(5) | ^3.0.0 || ^4.0.0(6) | โฅ14.16.0(3) |
| 0.0 | >=0.28.1 <1.0.0 || ^1 | ^3.0.0 | โฅ14.16.0(3) |
More details...
- Official support for version 4.x of vitest starts at 0.2.3.
- Requires support for
require(esm). - Same support as vitest.
- Official support for version 2.x of vitest starts at 0.1.2.
- Official support for version 3.x of vitest starts at 0.1.5.
- Official support for version 4.x of fast-check starts at 0.1.6.
File: packages/poisoning/README.md
`@fast-check/poisoning`
Set of utilities to ease detection and revert of poisoning
Why?
In JavaScript, "prototype poisoning" is one of the most common source for CVEs or zero days. It allows attackers to change the behaviour of some defaults like Array.prototype.map, Map, Set... so that they behave differently and can be leveraged for evil stuffs. This package can be used in addition to fast-check in order to detect poisoning that may occur during your property based tests.
Easy to use
The package comes with:
assertNoPoisoning: assert that the defaults known when first importing the package in your code have not been changedrestoreGlobals: restore the defaults so that any change that could have been detected byassertNoPoisoningwill be resolved
Minimal requirements
- Node โฅ20.19.0
File: packages/packaged/README.md
`@fast-check/packaged`
Utility package removing any files that will not be part of the final bundle published to npm registry
Why?
When publishing packages to npm registry, it is quite easy to forget about some files. It also happens many times that we want somehow to check the packaged bundle in some of our tests but totally forget that some files have not been added to the bundle and so that the final user will actually never be able to run this code.
This package mostly try to prevent this issue. It can easily be used in monorepos to emulate the bundled package when used against other packages of the monorepo to make sure others do not depend on internals or non published stuff.
Easy to use
Run the following command at the root of your package to drop any file that will not make it in the final bundle published to npm.
# With npm
npx -p @fast-check/packaged packaged
# With pnpm
pnpm --package=@fast-check/packaged dlx packaged
# With yarn
yarn dlx -p @fast-check/packaged packagedโ ๏ธ You may want to try with --dry-run flag first to give it a try.
It also comes with some extra flags:
--dry-run: do not drop any file or directory from the file system and only print what would have been removed--keep <name>: keep a root-level file or directory matching the exact name (not a glob pattern, can be specified multiple times, e.g.--keep node_modules --keep src)
Simple API
import { computePublishedFiles, removeNonPublishedFiles } from '@fast-check/packaged';
// Compute the list of all files that would be part of the bundle
// if we attempted to publish the packge defined at .
const publishedFilesRoot = await computePublishedFiles('.');
// Compute the list of all files that would be part of the bundle
// if we attempted to publish the packge defined at ./sub-directory
const publishedFilesSubDirectory = await computePublishedFiles('./sub-directory');
// Run the deletion of unwanted files
const { kept, removed } = await removeNonPublishedFiles('.', { dryRun: false, keep: [] });
// kept and removed are arrays of strings
// they may contain files or directoriesMinimal requirements
| @fast-check/packaged | node |
|---|---|
| 0.6.x | โฅ20.19.0(1) |
More details...
- Requires support for
require(esm).
File: packages/jest/README.md
`@fast-check/jest`
Bring the power of property based testing framework fast-check into Jest.@fast-check/jest simplifies the integration of fast-check into Jest testing framework.
Getting Started
Install @fast-check/jest:
npm install --save-dev @fast-check/jestIn order to work properly, @fast-check/jest requires jest to be installed.
We also highly recommend users to launch their tests using the --show-seed option provided by Jest. It ensures Jest will always print the seed by itself (requires Jest โฅ29.2.0).
jest --show-seedExample
import { test, fc } from '@fast-check/jest';
// for all a, b, c strings
// b is a substring of a + b + c
test.prop([fc.string(), fc.string(), fc.string()])('should detect the substring', (a, b, c) => {
return (a + b + c).includes(b);
});
// Or the exact same test but based on named parameters
test.prop({ a: fc.string(), b: fc.string(), c: fc.string() })('should detect the substring', ({ a, b, c }) => {
return (a + b + c).includes(b);
});The it and test functions returned by @fast-check/jest are just enriched versions of the ones coming from jest itself. They both come with .prop.
Please note that the properties accepted by @fast-check/jest as input can either be synchronous or asynchronous (even just PromiseLike instances). In other words, the predicate passed as the last argument can be asynchronous.
Remark: it and test have been introduced in 1.4.0. You have to refer to Deprecated API if you are using a version of @fast-check/jest <1.4.0.
Advanced
Support for variations of `test` and `it`
If you want to forward custom parameters to fast-check, test.prop and its variants accept an optional fc.Parameters (more).
@fast-check/jest also comes with support for .only, .skip, .todo and .concurrent from jest. It also accepts more complex ones such as .concurrent.failing or .concurrent.only.failing.
import { it, test, fc } from '@fast-check/jest';
// With custom `fc.Parameters`, here { seed: 4242 }
test.prop([fc.nat(), fc.nat()], { seed: 4242 })('should replay the test for the seed 4242', (a, b) => {
return a + b === b + a;
});
// With .skip
test.skip.prop([fc.string()])('should be skipped', (text) => {
return text.length === [...text].length;
});
// With it version
describe('with it', () => {
it.prop([fc.nat(), fc.nat()])('should run too', (a, b) => {
return a + b === b + a;
});
});Experimental worker-based runner
The following feature is experimental! When used it makes runners able to kill long running synchonous code. Meaning that it will make fast-check able to kill infinite loops blocking the main thread. So far, the feature does not fully support transformations performed via transform steps defined with jest.
The CommonJS approach would be:
const { init, fc } = require('@fast-check/jest/worker');
const { pathToFileURL } = require('node:url');
const { test, expect } = init(pathToFileURL(__filename));
// can also be passed options such as isolationLevel: init(pathToFileURL(__filename), {})
test.prop([fc.constant(null)])('should pass', (value) => {
expect(value).toBe(null);
});The ES Modules approach would be:
import { init, fc } from '@fast-check/jest/worker';
const { test, expect } = await init(new URL(import.meta.url));
// can also be passed options such as isolationLevel: init(new URL(import.meta.url), {})
test.prop([fc.constant(null)])('should pass', (value) => {
expect(value).toBe(null);
});โ ๏ธ Do not forget to add the await before init for the ES Module version!
Extra setup for `@fast-check/worker` 0.6.0 and later
Since @fast-check/worker is an ESM-only package, running it under Jest in CommonJS mode requires babel-jest to transpile it. Install the following dependencies:
npm install --save-dev babel-jest @babel/core @babel/preset-envThen add a babel.config.cjs at the root of your project:
module.exports = {
presets: [['@babel/preset-env', { targets: { node: 'current' }, modules: 'commonjs' }]],
};And update your Jest configuration to use babel-jest while excluding @fast-check/worker from the ignore patterns:
module.exports = {
transform: {
'^.+\\.[t|j]sx?$': 'babel-jest',
},
transformIgnorePatterns: ['/node_modules/(?!(?:@fast-check/worker)/)'],
};This ensures @fast-check/worker gets transpiled to CommonJS by Babel instead of being skipped. Without it, Jest will fail to load the ESM-only package.
For ES Modules mode, no extra setup is needed โ just make sure to run Jest with --experimental-vm-modules:
node --experimental-vm-modules node_modules/jest/bin/jest.jsMinimal requirements
| @fast-check/jest | jest | fast-check | node |
|---|---|---|---|
| ^2.0.0 | >=26.5.0(1)(2) | ^3.0.0 | >=14.15.0(3) and <18, >=18.17.0 and <19(4), >=20 |
| ^1.0.0 | >=26.5.0(1)(2) | ^3.0.0 | >=14.15.0(3) and <18, >=18.17.0 and <19(4), >=20 |
- (1) any version of
jestshould be greater or equal than 26.5.0 if you are usingcommonjs - (2) in order to use
esmbuild, you may need to enable experimental features of node, see here - (3) >=14.15.0 is the minimal requirements for
jest, >=12.17.0 is the one for@fast-check/jest - (4) timeout defined on jest might not be properly applied to fast-check for node 18 (until 18.17.0) and node 19, see #4004
File: packages/fast-check/README.md
Getting started
Hands-on tutorial and definition of Property Based Testing: ๐ see tutorial. Or directly try it online on our pre-configured CodeSandbox.
Property based testing frameworks check the truthfulness of properties. A property is a statement like: for all (x, y, ...) such that precondition(x, y, ...) holds predicate(x, y, ...) is true.
Install the module with: pnpm add -D fast-check or yarn add fast-check --dev or npm install fast-check --save-dev
Example of integration in mocha:
import fc from 'fast-check';
// Code under test
const contains = (text, pattern) => text.indexOf(pattern) >= 0;
// Properties
describe('properties', () => {
// string text always contains itself
it('should always contain itself', () => {
fc.assert(fc.property(fc.string(), (text) => contains(text, text)));
});
// string a + b + c always contains b, whatever the values of a, b and c
it('should always contain its substrings', () => {
fc.assert(
fc.property(fc.string(), fc.string(), fc.string(), (a, b, c) => {
// Alternatively: no return statement and direct usage of expect or assert
return contains(a + b + c, b);
}),
);
});
});In case of failure, the test raises a red flag. Its output should help you to diagnose what went wrong in your implementation. Example with a failing implementation of contain:
1) should always contain its substrings
Error: Property failed after 1 tests (seed: 1527422598337, path: 0:0): ["","",""]
Shrunk 1 time(s)
Got error: Property failed by returning false
Hint: Enable verbose mode in order to have the list of all failing values encountered during the runIntegration with other test frameworks: ava, jasmine, jest, mocha and tape.
More examples: simple examples, fuzzing and against various algorithms.
Useful documentations:
- ๐ Introduction to Property Based & Hands On
- ๐ฃ Built-in arbitraries
- ๐ง Custom arbitraries
- ๐โโ๏ธ Property based runners
- ๐ฅ Tips
- ๐ API Reference
- โญ Awesome fast-check
Why should I migrate to fast-check?
fast-check has initially been designed in an attempt to cope with limitations I encountered while using other property based testing frameworks designed for JavaScript:
- Types: strong and up-to-date types - thanks to TypeScript
- Extendable: easy
mapmethod to derive existing arbitraries while keeping shrink [more] - some frameworks ask the user to provide both a->b and b->a mappings in order to keep a shrinker - Extendable: kind of flatMap-operation called
chain[more] - able to bind the output of an arbitrary as input of another one while keeping the shrink working - Extendable: precondition checks with
fc.pre(...)[more] - filtering invalid entries can be done directly inside the check function if needed - Extendable: easily switch from fake data in tests to property based with
fc.gen()[more] - generate random values within your predicates - Smart: ability to shrink on
fc.oneof[more] - surprisingly some frameworks don't - Smart: biased by default - by default it generates both small and large values, making it easier to dig into counterexamples without having to tweak a size parameter manually
- Debug: verbose mode [more][tutorial] - easier troubleshooting with verbose mode enabled
- Debug: replay directly on the minimal counterexample [tutorial] - no need to replay the whole sequence, you get directly the counterexample
- Debug: custom examples in addition of generated ones [more] - no need to duplicate the code to play the property on custom examples
- Debug: logger per predicate run [more] - simplify your troubleshoot with fc.context and its logging feature
- Unique: model based approach [more][article] - use the power of property based testing to test UI, APIs or state machines
- Unique: detect race conditions in your code [more][tutorial] - shuffle the way your promises and async calls resolve using the power of property based testing to detect races
- Unique: simplify user definable corner cases [more] - simplify bug resolution by asking fast-check if it can find an even simpler corner case
For more details, refer to the documentation in the links above.
Trusted
fast-check has been trusted for years by big projects like: jest, jasmine, fp-ts, io-ts, ramda, js-yaml, query-string...
Powerful
It also proved useful in finding bugs among major open source projects such as jest, query-string... and many others.
Compatibility
Here are the minimal requirements to use fast-check properly without any polyfills:
| fast-check | node | ECMAScript version | TypeScript (optional) |
|---|---|---|---|
| 4.x | โฅ12.17.0(1) | ES2020 | โฅ5.0 |
| 3.x | โฅ8(2) | ES2017 | โฅ4.1(3) |
| 2.x | โฅ8(2) | ES2017 | โฅ3.2(4) |
| 1.x | โฅ0.12(2) | ES3 | โฅ3.0(4) |
More details...
- Even if version 12.x should support most of the ES2020 features that will be leveraged by the version 4, we recommend relying at least on version 14.x of Node as it supports all the targeted specification. In addition, we highly encourage switching to still supported LTS versions of Node and not sticking to unsupported versions for too long.
- Except for features that cannot be polyfilled - such as
bigint-related ones - all the capabilities of fast-check should be usable given you use at least the minimal recommended version of node associated to your major of fast-check. - Require either lib or target โฅ ES2020 or
@types/nodeto be installed. - Require either lib or target โฅ ES2015 or
@types/nodeto be installed.
Contributors โจ
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome! Become one of them
Sponsors ๐ธ
Many individuals and companies offer their financial support to the project, a huge thanks to all of them too ๐
You can also become one of them by contributing via GitHub Sponsors or OpenCollective.
File: packages/ava/README.md
`@fast-check/ava`
Bring the power of property based testing framework fast-check into AVA.@fast-check/ava simplifies the integration of fast-check into AVA testing framework.
Getting Started
Install @fast-check/ava:
npm install --save-dev @fast-check/avaIn order to work properly, @fast-check/ava requires ava to be installed.
Example
import { testProp, fc } from '@fast-check/ava';
// for all a, b, c strings
// b is a substring of a + b + c
testProp('should detect the substring', [fc.string(), fc.string(), fc.string()], (t, a, b, c) => {
t.true((a + b + c).includes(b));
});The property is passed AVA's t argument as its first parameter, and the value of each arbitrary for the current test case for the rest of the parameters.
@fast-check/ava supports all of AVA's assertions and like AVA, it supports synchronous and asynchronous functions, including promises, observables, and callbacks. See AVA's documentation for more information.
โ ๏ธ WARNING: When relying on @fast-check/ava, returning true or false in your predicates is not taken into account. The library wants assertions or plans to be defined as ava itself does. Nonetheless you can still use primitives such as fc.pre to cut runs at the middle if some invariants are unmeet: the started plan (if any) will just be ignored.
Advanced
`fast-check` Parameters
testProp accepts an optional fc.Parameters for forwarding custom parameters to fast-check (more).
import { testProp, fc } from '@fast-check/ava';
testProp(
'should detect the substring',
[fc.string(), fc.string(), fc.string()],
(t, a, b, c) => {
t.true((a + b + c).includes(b));
},
{ numRuns: 10 }, // Example of parameters
);AVA Modifiers
@fast-check/ava also comes with .only, .serial .skip, and .failing modifiers from AVA.
import { testProp, fc } from '@fast-check/ava';
testProp(
'should replay the test for the seed 4242',
[fc.nat(), fc.nat()],
(t, a, b) => {
t.is(a + b, b + a);
},
{ seed: 4242 },
);
testProp.skip('should be skipped', [fc.string()], (t, text) => {
t.is([...text].length, text.length);
});AVA `before`/`after` Hooks
@fast-check/ava exposes AVA's before/after hooks:
import { testProp, fc } from '@fast-check/ava';
testProp.before((t) => {
connectToDatabase();
});
testProp();
// ... omitted for brevity
testProp.after((t) => {
closeDatabaseConnection();
});AVA Execution Context
@fast-check/ava mirror's AVA's procedure for customizing the test execution context:
import { fc, testProp as anyTestProp, PropertyTestInterface } from '@fast-check/ava';
type TestContext = {
state: string;
};
const testProp = anyTestProp as PropertyTestInterface<TestContext>;
testProp('should reach terminal state', [fc.string()], (t, received) => {
// here t is typed as ExecutionContext<TestContext>
console.log(t.context.state); // logs 'uninitialized'
// ... omitted for brevity
});Minimal requirements
| @fast-check/ava | AVA | fast-check | node |
|---|---|---|---|
| 3.0 | ^4 || ^5 || ^6 | ^3 || ^4 | โฅ20.19.0(1) |
| 2.0 | ^4 || ^5 || ^6 | ^3 || ^4 | โฅ12.22.0(2) |
| 1.0 | ^4 || ^5 || ^6 | ^3 | โฅ12.22.0(2) |
More details...
- Requires support for
require(esm). - As for ava 4.