Skip to content

Property-Based Testing with Fast-Check

Posted on:November 30, 2023 at 11:11 AM

In this artcile we’re delving into the world of property testing, a concept that might sound complex but is incredibly powerful in ensuring robust applications.

Unlike traditional testing methods, property testing doesn’t focus on specific inputs and outputs. Instead, it verifies the characteristics or properties of your code – ensuring they hold true under various, often unexpected, scenarios. Think of it as stress-testing your code’s logic across a broad range of possibilities.

Property Testing vs. Unit Testing

Now, you might wonder, “How is this different from unit testing?” Good question! Unit testing involves writing test cases for specific input-output pairs. You’re essentially predicting and testing exact results. Property testing, on the other hand, is more abstract. It’s not about checking specific outcomes but ensuring that certain properties of your code remain consistent, no matter what inputs are thrown at it.

When to Use Property Testing

Property testing shines in scenarios where inputs are too numerous or complex to individually test. It’s perfect for:

Introduction to Fast-Check

Enter Fast-Check, a fantastic tool for property testing in JavaScript and TypeScript environments. It’s designed to seamlessly integrate with your existing testing frameworks, bringing the power of property testing to your frontend development toolkit.

Fast-Check’s Core Concepts

Fast-Check revolves around three key concepts:

  1. Runner: This is the engine that runs your property tests. It generates random inputs, executes tests, and reports findings.

  2. Property: In Fast-Check terminology, a property is a testable assertion about your code. It’s a condition or rule your code should always satisfy.

  3. Arbitraries: These are generators that produce a wide range of random values. They feed into your tests, ensuring your properties are checked against a diverse set of inputs.

Testing with Fast-Check

Let’s see Fast-Check in action by creating a simple example of using Fast-Check to test an array sorting function. This test will check a basic property: after sorting an array, the elements should be in non-descending order. We’ll use Fast-Check to generate random arrays of numbers and then test if the sorting function behaves as expected for these arrays.

First, here’s a basic sorting function we want to test:

function sortArray(arr) {
    return arr.slice().sort((a, b) => a - b);
}

Now, let’s write a Fast-Check test for this function. We’ll use fc.array(fc.integer()) to generate random arrays of integers:

import fc from 'fast-check';

describe('Array Sorting Tests', () => {
    test('should sort the array in non-descending order', () => {
        fc.assert(
            fc.property(
                fc.array(fc.integer()), 
                (arr) => {
                    const sorted = sortArray(arr);
                    for (let i = 1; i < sorted.length; i++) {
                        if (sorted[i - 1] > sorted[i]) {
                            return false; // The property is violated
                        }
                    }
                    return true; // The property holds
                }
            )
        );
    });
});

In this test:

This is a basic example. Fast-Check can be used to test more complex properties and scenarios, making it a powerful tool in your testing arsenal.

Integrating Fast-Check with Testing Frameworks

Let’s dive into how you can integrate Fast-Check with some of the most popular frontend testing frameworks, particularly focusing on Jest, a widely-used choice among developers.

Installing Fast-Check

First things first, you’ll need to install Fast-Check. It’s a breeze! Assuming you have Node.js installed, open your terminal and navigate to your project’s root directory. Then, simply run:

npm install fast-check --save-dev

This command installs Fast-Check and adds it to your project’s development dependencies.

Using Fast-Check with Jest

Jest is loved by many for its simplicity and zero-configuration setup. Combining Jest with Fast-Check allows you to write powerful property tests with ease.

Here’s how to get started:

  1. Write Your Test: In your Jest test file, import Fast-Check alongside Jest:

    import fc from 'fast-check';
  2. Create Your Test Block: Use Jest’s test or it functions to define your test block. Inside, utilize Fast-Check’s fc.assert and fc.property to write your property tests.

    Here’s a simple example testing a function that should always return true:

    test('my function should always return true', () => {
        fc.assert(
            fc.property(fc.anything(), (input) => {
                expect(myFunction(input)).toBe(true);
            })
        );
    });

    In this example, fc.anything() generates all kinds of random inputs to test myFunction.

  3. Run Your Tests: Just like any Jest tests, run them using your preferred method, such as the command line or a script in your package.json.

Integrating with Other Frameworks

Fast-Check is not limited to Jest. It can be integrated with many other testing frameworks like Mocha, Jasmine, or even custom testing setups. The process is similar:

  1. Install Fast-Check as shown above.
  2. Import it into your test files.
  3. Write your property tests using Fast-Check’s API, wrapped inside your framework’s test functions.

Next Steps

Property testing with Fast-Check can significantly enhance the reliability of your frontend code. It’s a proactive approach to uncovering issues and ensuring your code behaves as expected under a myriad of situations.

Ready to dive deeper? Start by experimenting with simple properties in your existing projects. Explore Fast-Check’s documentation for detailed guides and examples. Embrace this powerful testing paradigm and watch as it transforms your frontend development journey!


Remember, testing is not just about finding bugs. It’s about ensuring a seamless, robust user experience. Happy testing! 🚀🧪