Skip to content

Commit

Permalink
📝 Document integration with other test runners (#5121)
Browse files Browse the repository at this point in the history
**Description**

<!-- Please provide a short description and potentially linked issues
justifying the need for this PR -->

Integrating fast-check with test runners is crucial for users to be able
to use it. As such we started a few months ago to document some
integrations (Jest only). We planned to add others but never did that
until now.

The newly added batch is around native test runners coming with
runtimes. Others will come such as Ava and Vitest but so far we focused
on the bare metal integrations directly with runtimes.

<!-- * Your PR is fixing a bug or regression? Check for existing issues
related to this bug and link them -->
<!-- * Your PR is adding a new feature? Make sure there is a related
issue or discussion attached to it -->

<!-- You can provide any additional context to help into understanding
what's this PR is attempting to solve: reproduction of a bug, code
snippets... -->

**Checklist** — _Don't delete this checklist and make sure you do the
following before opening the PR_

- [x] The name of my PR follows [gitmoji](https://gitmoji.dev/)
specification
- [x] My PR references one of several related issues (if any)
- [x] New features or breaking changes must come with an associated
Issue or Discussion
- [x] My PR does not add any new dependency without an associated Issue
or Discussion
- [x] My PR includes bumps details, please run `yarn bump` and flag the
impacts properly
- [x] My PR adds relevant tests and they would have failed without my PR
(when applicable)

<!-- More about contributing at
https://github.com/dubzzz/fast-check/blob/main/CONTRIBUTING.md -->

**Advanced**

<!-- How to fill the advanced section is detailed below! -->

- [x] Category: 📝 Add or update documentation
- [x] Impacts: None

<!-- [Category] Please use one of the categories below, it will help us
into better understanding the urgency of the PR -->
<!-- * ✨ Introduce new features -->
<!-- * 📝 Add or update documentation -->
<!-- * ✅ Add or update tests -->
<!-- * 🐛 Fix a bug -->
<!-- * 🏷️ Add or update types -->
<!-- * ⚡️ Improve performance -->
<!-- * _Other(s):_ ... -->

<!-- [Impacts] Please provide a comma separated list of the potential
impacts that might be introduced by this change -->
<!-- * Generated values: Can your change impact any of the existing
generators in terms of generated values, if so which ones? when? -->
<!-- * Shrink values: Can your change impact any of the existing
generators in terms of shrink values, if so which ones? when? -->
<!-- * Performance: Can it require some typings changes on user side?
Please give more details -->
<!-- * Typings: Is there a potential performance impact? In which cases?
-->
  • Loading branch information
dubzzz authored Jul 12, 2024
1 parent e3ea712 commit addef65
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
slug: /tutorials/setting-up-your-test-environment/property-based-testing-with-bun-test-runner/
description: Enrich Bun test runner with Property-Based Testing capabilities. Discover best practices to setup fast-check for it
sidebar_label: With Bun test runner
image: /img/socials/fast-check-bun.png
---

# Property Based Testing with Bun test runner

You're using [Bun](https://bun.sh/) and you want to explore property-based testing with it. Stay here! This quick tutorial will give you the basics to get started.

## Basic setup

First, add fast-check as a development dependency to your project:

```bash
bun install -D fast-check
```

Congratulations, everything is ready to start using Property-Based Tests with the Bun test runner 🚀

## Your first test

For our first test, we will consider a function called `decompose`. `decompose` takes an integer value between 1 (included) and 2,147,483,647 (included) and decomposes it into the list of its prime factors. For example, the value `20` can be decomposed as `20 = 2 x 2 x 5`, where neither `2` nor `5` can be decomposed further.

One of the things we could assess about such an algorithm is that the array of prime factors should multiply back to the original value. In other words, whatever input we pass to our function (within the accepted range), we expect it to provide us a list of factors that, when multiplied together, give us back our original value.

```js title="decompose.spec.ts"
import { describe, it, expect } from 'bun:test';
import fc from 'fast-check';

describe('decompose', () => {
it('should produce an array such that the product equals the input', () => {
fc.assert(
fc.property(fc.integer({ min: 2, max: 2 ** 31 - 1 }), (n) => {
const factors = decompose(n);
const productOfFactors = factors.reduce((a, b) => a * b, 1);
return productOfFactors === n;
})
);
});
});

// Code under test: should rather be imported from another file
function decompose(n: number): number[] {
// Quick implementation: the maximal number supported is 2**31-1
let done = false;
const factors: number[] = [];
while (!done) {
done = true;
const stop = Math.sqrt(n);
for (let i = 2; i <= stop; ++i) {
if (n % i === 0) {
factors.push(i);
n = Math.floor(n / i);
done = false;
break;
}
}
}
return [...factors, n];
}
```

You can now execute it by running the following command in a terminal:

```bash
bun test
```

You've written and executed your first Property-Based Test using the Bun test runner 🚀

## Going further

The example of `decompose` can be extended much further with additional properties. If you want to explore more properties you could come up with, you can read [this article](https://dev.to/dubzzz/advent-of-pbt-2021-day-2-solution-367b).

fast-check is not only about testing simple algorithms, it can be extended to much more complex pieces of code, including:

- [checking asynchronous code](/docs/core-blocks/properties/#asynchronous-properties),
- [detecting race conditions](/docs/tutorials/detect-race-conditions/),
- [building complex inputs](/docs/core-blocks/arbitraries/), and more.

Our documentation is the best place to start to discover all these capabilities.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
slug: /tutorials/setting-up-your-test-environment/property-based-testing-with-deno-test-runner/
description: Bring Property-Based Testing capabilities into Deno with fast-check
sidebar_label: With Deno test runner
image: /img/socials/fast-check-deno.png
---

# Property Based Testing with Deno test runner

Want to start playing with property-based testing in [Deno](https://deno.com/)? Welcome to this short and concise tutorial on integrating fast-check within Deno.

## Your first test

Let's write a test for [FizzBuzz](https://en.wikipedia.org/wiki/Fizz_buzz) using fast-check.

```js title="fizzbuzz.test.ts"
import { assertStringIncludes } from "jsr:@std/assert";
import fc from "npm:fast-check";

Deno.test({
name: "should print Fizz whenever divisible by 3",
fn() {
fc.assert(
fc.property(
fc.nat().map((n) => n * 3),
(n) => {
assertStringIncludes(fizzbuzz(n), "Fizz");
}
)
);
},
});

// Code under test: should rather be imported from another file
function fizzbuzz(n: number): string {
return n % 3 === 0
? n % 5 === 0
? "Fizz Buzz"
: "Fizz"
: n % 5 === 0
? "Buzz"
: String(n);
}
```

You can now execute it by running the following command in a terminal:

```bash
deno test
```

You've written and executed your first Property-Based Test using the Deno test runner 🚀

## Going further

Property-based testing can be leveraged to test complex systems. This snippet was just a simple Hello-World example to give you a basic starting point. Our documentation provides advanced tricks to push the technique further, including [detecting race conditions](/docs/tutorials/detect-race-conditions/) and [finding vulnerabilities](/blog/2023/09/21/detect-prototype-pollution-automatically/).

FizzBuzz alone can also be extended with more properties. You may want to refer to [this article](https://dev.to/dubzzz/advent-of-pbt-2021-day-3-solution-366l) for more ideas.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
---
sidebar_position: 1
slug: /tutorials/setting-up-your-test-environment/property-based-testing-with-jest/
description: Discover how to configure the integration of Property-Based Testing capabilities within Jest. Learn best practices to setup fast-check for it
sidebar_label: With Jest
image: /img/socials/fast-check-jest.png
---

# Property Based Testing with Jest
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
slug: /tutorials/setting-up-your-test-environment/property-based-testing-with-nodejs-test-runner/
description: Extend the Node.js test runner with Property-Based Testing capabilities. Discover best practices to setup fast-check for it
sidebar_label: With Node.js test runner
image: /img/socials/fast-check-nodejs.png
---

# Property Based Testing with Node.js test runner

Officially made stable with Node.js v20, there is now an [official test runner](https://nodejs.org/en/blog/announcements/v20-release-announce#stable-test-runner) in Node.js since 2023. As with any other test runner, fast-check can be integrated with just a few steps.

The following tutorial provides some pointers and tricks to achieve this integration smoothly.

## Basic setup

Add fast-check to your set of dependencies:

```bash npm2yarn
npm install --save-dev fast-check
```

Congratulations, everything is ready to start using Property-Based Tests with the Node.js test runner 🚀

## Your first test

For our first test, we will test an algorithm computing a value of the [Fibonacci sequence](https://en.wikipedia.org/wiki/Fibonacci_sequence). Our property-based test will assess that our implementation respects the rule: `fibo(n) = fibo(n-1) + fibo(n-2)`.

```js title="fibo.test.js"
const assert = require('node:assert');
const { test } = require('node:test');
const fc = require('fast-check');

test('should follow the rule: fibo(n) = fibo(n-1) + fibo(n-2)', () => {
fc.assert(
fc.property(fc.integer({ min: 2, max: 78 }), (n) => {
assert.equal(fibo(n), fibo(n - 1) + fibo(n - 2));
}),
);
});

// Code under test: should rather be imported from another file
function fibo(n) {
// Note: n must be in the range 0 (included) to 78 (included)
let a = 0;
if (n === 0) {
return a;
}
let b = 1;
for (let i = 1; i !== n; ++i) {
const c = a + b;
a = b;
b = c;
}
return b;
}
```

You can now execute it by running the following command in a terminal:

```bash
node --test
```

You've written and executed your first Property-Based Test using the Node.js test runner 🚀

## Going further

The Fibonacci sequence isn't just about `fibo(n) = fibo(n-1) + fibo(n-2)`. Tests can be extended much further with additional properties to confirm the implementation. You can read [this article](https://dev.to/dubzzz/advent-of-pbt-2021-day-7-solution-4lf3) to explore more properties for it.

There are many advanced techniques to manage fast-check like a pro. Whether you want to start experimenting with [asynchronous properties](/docs/core-blocks/properties/#asynchronous-properties), [detecting race conditions](/docs/tutorials/detect-race-conditions/), [building complex values](/docs/core-blocks/arbitraries/), or more, our documentation is the best place to start to discover all these details and subtleties.
3 changes: 3 additions & 0 deletions website/static/img/socials/fast-check-bun.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions website/static/img/socials/fast-check-deno.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions website/static/img/socials/fast-check-jest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions website/static/img/socials/fast-check-nodejs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit addef65

Please sign in to comment.