patterntypescriptTip
Fuzz testing: discover edge cases by feeding random inputs to parsing and validation code
Viewed 0 times
fast-checkproperty-based testingfuzzingfuzz testingarbitrary inputshrinking
Problem
Manually written test cases cover the happy path and a few known edge cases. Parsing functions, serializers, input validators, and cryptographic code have combinatorially large input spaces that manual tests cannot cover.
Solution
Use
fast-check for property-based fuzzing in TypeScript. Define properties that must hold for all inputs and let fast-check generate thousands of random examples, including edge cases like empty strings, huge numbers, and Unicode surrogates. When a failing case is found, fast-check shrinks it to the minimal reproducer.Why
Fuzzing explores input spaces that humans are systematically blind to. It reliably finds off-by-one errors, integer overflows, unhandled Unicode, and null pointer dereferences that example-based tests miss.
Gotchas
- fast-check's arbitrary composition can produce invalid domain objects; constrain arbitraries with fc.filter() or fc.map()
- Fuzz tests are slower than example tests — cap the number of runs or use smaller run counts in CI
- Property-based tests require identifying true invariants (not just happy-path outputs), which demands deeper domain understanding
- Shrinking can take time; increase the shrink timeout for complex arbitraries
Code Snippets
Round-trip property test with fast-check
import * as fc from 'fast-check';
it('parse(serialize(x)) === x for any string', () => {
fc.assert(
fc.property(fc.string(), (s) => {
expect(parse(serialize(s))).toBe(s);
}),
);
});Revisions (0)
No revisions yet.