fast-check
Property based testing framework for JavaScript (like QuickCheck) written in TypeScript
Top Related Projects
Generative testing for JavaScript
Write powerful and concise tests. Property-based testing for JavaScript. Like QuickCheck.
Quick Overview
fast-check is a property-based testing framework for JavaScript and TypeScript. It allows developers to write more concise and powerful tests by specifying the properties of their code rather than specific test cases. This approach can help catch edge cases and uncover hidden bugs more effectively than traditional unit testing.
Pros
- Powerful Property-Based Testing: fast-check provides a wide range of built-in generators for common data types, making it easy to create complex test scenarios.
- Flexible and Extensible: Developers can create custom generators and shrink functions to tailor the testing to their specific needs.
- Comprehensive Reporting: The library provides detailed reports on failed test cases, including the input values that triggered the failure.
- Supports Multiple Environments: fast-check can be used in both Node.js and browser environments, as well as with popular testing frameworks like Jest and Mocha.
Cons
- Steep Learning Curve: Property-based testing can be a new concept for developers, and it may take some time to understand how to effectively use fast-check.
- Potential for Slow Tests: Generating and running a large number of test cases can slow down the testing process, especially for complex properties.
- Dependency on External Libraries: fast-check relies on several external libraries, which can increase the overall project's complexity and maintenance overhead.
- Limited Debugging: Debugging failed test cases can be more challenging than with traditional unit tests, as the library focuses on reporting the input values rather than the specific code path that triggered the failure.
Code Examples
Here are a few examples of how to use fast-check:
- Basic Property-Based Test:
import fc from 'fast-check';
// Specify the property to test
const prop = fc.property(
fc.integer(),
fc.integer(),
(a, b) => a + b === b + a
);
// Run the test
fc.assert(prop);
- Custom Generator:
import fc from 'fast-check';
// Define a custom generator for a user object
const userArb = fc.record({
name: fc.string(),
age: fc.integer(18, 80),
email: fc.emailAddress()
});
// Use the custom generator in a property-based test
const prop = fc.property(userArb, (user) => {
// Test some property of the user object
return user.age >= 18;
});
fc.assert(prop);
- Shrinking and Reporting:
import fc from 'fast-check';
// Define a property that should fail
const prop = fc.property(
fc.array(fc.integer()),
(arr) => arr.length > 0 && arr[0] > 0
);
// Run the test and handle the failure
fc.assert(prop, {
numRuns: 1000, // Run the test 1000 times
seed: 42, // Use a specific seed for reproducibility
onFailure: (failure) => {
// Inspect the failed test case
console.log('Failed with input:', failure.counterexample);
}
});
Getting Started
To get started with fast-check, you can install the library using npm or yarn:
npm install fast-check
or
yarn add fast-check
Once installed, you can import the library and start writing property-based tests:
import fc from 'fast-check';
// Define a property to test
const prop = fc.property(
fc.integer(),
fc.integer(),
(a, b) => a + b === b + a
);
// Run the test
fc.assert(prop);
For more advanced usage, you can refer to the fast-check documentation for information on custom generators, shrinking, and integration with popular testing frameworks.
Competitor Comparisons
Generative testing for JavaScript
Pros of testcheck-js
- Powerful Property-Based Testing: testcheck-js provides a robust property-based testing framework, allowing you to define high-level properties of your code and automatically generate test cases to verify those properties.
- Flexible Generators: testcheck-js offers a wide range of built-in generators for common data types, making it easy to create complex test data for your tests.
- Integrates with Mocha and Jest: testcheck-js can be easily integrated with popular testing frameworks like Mocha and Jest, allowing you to seamlessly incorporate property-based testing into your existing test suites.
Cons of testcheck-js
- Limited Documentation: Compared to Fast-Check, the documentation for testcheck-js is relatively sparse, which can make it more challenging for new users to get started.
- Smaller Community: Fast-Check has a larger and more active community, with more contributors and a wider range of available resources and support.
- Fewer Features: While testcheck-js is a powerful property-based testing framework, it lacks some of the advanced features and utilities found in Fast-Check, such as support for asynchronous testing and custom shrinking strategies.
Code Comparison
Here's a simple example of how to use Fast-Check and testcheck-js to test the same property:
Fast-Check:
import fc from 'fast-check';
const prop = fc.property(
fc.integer(),
fc.integer(),
(a, b) => a + b === b + a
);
fc.assert(prop);
testcheck-js:
import { check, gen } from 'testcheck';
const prop = check(
gen.tuple([gen.integer(), gen.integer()]),
([a, b]) => a + b === b + a
);
Both examples define a property that checks if the sum of two integers is commutative. The main difference is the syntax and the way the generators are defined.
Write powerful and concise tests. Property-based testing for JavaScript. Like QuickCheck.
Pros of jsverify/jsverify
- Mature and Established: jsverify has been around since 2013 and has a large and active community, making it a well-established and reliable property-based testing library.
- Extensive Documentation: The jsverify documentation is comprehensive and provides detailed examples and usage guides, making it easier for developers to get started.
- Supports Multiple Languages: While primarily a JavaScript library, jsverify also supports other languages like TypeScript, PureScript, and Haskell, making it more versatile.
Cons of jsverify/jsverify
- Limited Customization: Compared to Fast-Check, jsverify may have fewer options for customizing the property-based testing process, which could be a limitation for more complex use cases.
- Slower Performance: Some users have reported that Fast-Check outperforms jsverify in terms of execution speed, especially for larger test suites.
Code Comparison
Fast-Check:
import fc from 'fast-check';
fc.assert(
fc.property(
fc.integer(),
fc.string(),
(num, str) => {
// Your test logic here
return num > 0 && str.length > 0;
}
)
);
jsverify:
const jsc = require('jsverify');
jsc.assert(
jsc.forall(
jsc.integer(),
jsc.string(),
(num, str) => {
// Your test logic here
return num > 0 && str.length > 0;
}
)
);
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Property based testing framework for JavaScript/TypeScript
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: 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 run
Integration 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
map
method 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) |
---|---|---|---|
3.x | â¥8(1) | ES2017 | â¥4.1(2) |
2.x | â¥8(1) | ES2017 | â¥3.2(3) |
1.x | â¥0.12(1) | ES3 | â¥3.0(3) |
More details...
- 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/node
to be installed. - Require either lib or target ⥠ES2015 or
@types/node
to be installed.
ReScript bindings
Bindings to use fast-check in ReScript are available in package rescript-fast-check. They are maintained by @TheSpyder as an external project.
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.
Top Related Projects
Generative testing for JavaScript
Write powerful and concise tests. Property-based testing for JavaScript. Like QuickCheck.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot