Property Based Testing with Bun test runner
You're using Bun 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:
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.
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:
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.
fast-check is not only about testing simple algorithms, it can be extended to much more complex pieces of code, including:
Our documentation is the best place to start to discover all these capabilities.