Vitest Integration
Relevant source files
The following files were used as context for generating this wiki page:The @fast-check/vitest package provides a seamless integration of the fast-check property-based testing framework with the Vitest test runner. It extends Vitest's native test and it functions to support two powerful testing modes: a full-fledged property-based testing mode and a lightweight "one-time random" mode for introducing controlled, reproducible randomness into standard unit tests.
This integration simplifies the process of writing robust, property-based tests in a Vitest environment, leveraging the full capabilities of fast-check for generating a wide variety of inputs, detecting edge cases, and shrinking failing test cases to their minimal form.
Sources: packages/vitest/README.md
Setup and Installation
To use the integration, you need to install the @fast-check/vitest package as a development dependency.
npm install --save-dev @fast-check/vitest
Sources: packages/vitest/README.md
The package has peer dependencies on fast-check and vitest, which must also be present in your project.
Sources: packages/vitest/package.json:34-36
Minimal Requirements
The compatibility between @fast-check/vitest, vitest, and fast-check is outlined in the table below.
| @fast-check/vitest | vitest | fast-check | Node |
|---|---|---|---|
| 0.2 | ^1 || ^2 || ^3 || ^4 | ^3.0.0 || ^4.0.0 | ≥18 |
| 0.1 | >=0.28.1 | ^3.0.0 || ^4.0.0 | ≥14.16.0 |
| 0.0 | >=0.28.1 <1.0.0 || ^1 | ^3.0.0 | ≥14.16.0 |
Support for Vitest v4 was officially added in @fast-check/vitest v0.2.3.
Support for fast-check v4 was officially added in @fast-check/vitest v0.1.6.
Sources: packages/vitest/README.md:100-114, packages/vitest/CHANGELOG.md:10,50
Core Functionality
The package enhances Vitest by providing two distinct modes for incorporating fast-check's capabilities.
Full Property-Based Mode
This mode enables comprehensive, randomized testing by running a test function against numerous generated inputs. It is accessed via the .prop modifier on the test and it functions.
The .prop function accepts an array of fast-check arbitraries and a property function. The property function will be executed multiple times with values generated by the arbitraries.
The following diagram illustrates the execution flow of a test using test.prop.
This diagram shows how test.prop wraps a standard Vitest test, within which fc.assert manages the repeated execution and shrinking logic.
Sources: packages/vitest/README.md:52-65
Usage Examples
You can provide arbitraries as an array or as a named object. The property can be synchronous or asynchronous.
import { test, fc } from '@fast-check/vitest';
// Using an array of arbitraries
test.prop([fc.string(), fc.string(), fc.string()])('should detect the substring', (a, b, c) => {
return (a + b + c).includes(b);
});
// Using a named object of arbitraries
test.prop({ a: fc.string(), b: fc.string(), c: fc.string() })('should detect the substring', ({ a, b, c }) => {
return (a + b + c).includes(b);
});
Sources: packages/vitest/README.md:55-65
One-Time Random Mode
Introduced in version 0.2.0, this mode extends Vitest's standard test and it functions to allow for controlled, reproducible randomness within a single test execution. It does not run the test multiple times but provides a deterministic way to generate random values.
To use this mode, define your test function to accept an object with a generator function, conventionally named g.
Sources: packages/vitest/CHANGELOG.md:21-24, packages/vitest/README.md:29-35
Usage Example
The g function takes a fast-check arbitrary and returns a single, deterministically generated value based on the test's seed.
import { test, fc } from '@fast-check/vitest';
import { expect } from 'vitest';
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);
});
Sources: packages/vitest/README.md:37-50
If a test using g fails, fast-check reports the failure along with the seed, ensuring reproducibility.
The following sequence diagram shows the interaction during a test run with the g generator.
This diagram illustrates how the test function requests a random value from the g generator, which in turn uses fast-check to produce a deterministic value for that specific test run.
Sources: website/blog/2025-03-28-beyond-flaky-tests-bringing-controlled-randomness-to-vitest/index.md, packages/vitest/test/vitest-fast-check.spec.ts:281-295
Test Runner Modifiers
@fast-check/vitest supports chaining standard Vitest modifiers like .only, .skip, .todo, .concurrent, and .fails with .prop. This allows for flexible control over test execution.
| Modifier | Description |
|---|---|
.prop | Defines a property-based test. |
.only.prop | Runs only this property-based test. |
.skip.prop | Skips this property-based test. |
.todo.prop | Marks this property-based test as a "todo". |
.concurrent.prop | Runs this property-based test concurrently with others. |
.fails.prop | Expects this property-based test to fail. |
.concurrent.skip... | Modifiers can be chained to create more complex execution rules. |
Sources: packages/vitest/README.md:80-82, packages/vitest/test/vitest-fast-check.spec.ts:74-168
The internal tests for @fast-check/vitest confirm that these modifiers work at various chain depths, such as test.concurrent.fails.only.prop.
Sources: packages/vitest/test/vitest-fast-check.spec.ts:171-218
Configuration
You can customize the behavior of fast-check at both a global and a local, per-test level.
Local Parameters
To forward custom parameters to fast-check for a specific property, pass an fc.Parameters object as the second argument to test.prop. This is useful for setting a specific seed or numRuns for a single test.
import { test, fc } from '@fast-check/vitest';
// This test will always run with the same seed, making it deterministic.
test.prop([fc.nat(), fc.nat()], { seed: 4242 })('should replay the test for the seed 4242', (a, b) => {
return a + b === b + a;
});
// This test will run only 5 times instead of the default.
test.prop([fc.string()], { numRuns: 5 })('property', (_ignored) => {
return true;
});
Sources: packages/vitest/README.md:84-86, packages/vitest/test/vitest-fast-check.spec.ts:128-145
Global Parameters
To change the default parameters for all tests, use fc.configureGlobal. This is useful for setting a global seed to reproduce a failing run or for disabling shrinking during debugging.
import { fc } from '@fast-check/vitest';
// Re-run all tests with a specific seed
fc.configureGlobal({ seed: 12345 });
// Or disable shrinking to see the original failing value
fc.configureGlobal({ endOnFailure: true });
Sources: packages/vitest/README.md:40-43, packages/vitest/test/vitest-fast-check.spec.ts:147-168
Conclusion
The @fast-check/vitest package is a powerful tool that integrates property-based testing deeply into the Vitest ecosystem. By extending the familiar test and it APIs, it provides a low-friction entry point to property-based testing via test.prop and enhances standard unit tests with controlled randomness through the g generator. Its support for standard Vitest modifiers and flexible configuration options makes it an essential addition for developers looking to build more robust and reliable applications.
Sources: packages/vitest/README.md, website/blog/2025-03-28-beyond-flaky-tests-bringing-controlled-randomness-to-vitest/index.md