or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced

combinators.mdconcurrency-testing.mdmodel-based-testing.md
configuration.mdindex.md
tile.json

tessl/npm-fast-check

Property based testing framework for JavaScript (like QuickCheck)

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/fast-check@4.5.x

To install, run

npx @tessl/cli install tessl/npm-fast-check@4.5.0

index.mddocs/

fast-check

Property-based testing framework for JavaScript and TypeScript. Automatically generates test cases from specifications to discover edge cases and bugs.

Installation

npm install fast-check --save-dev

Package Information

  • Package Name: fast-check
  • Package Type: npm
  • Language: TypeScript
  • Version: 4.5.3

Imports

ES Module:

import fc from 'fast-check';
// Or import specific exports
import { assert, property, integer, string } from 'fast-check';

CommonJS:

const fc = require('fast-check');
// Or destructure specific exports
const { assert, property, integer, string } = require('fast-check');

Quick Start

Write your first property test:

import fc from 'fast-check';

// Test that string concatenation is associative
fc.assert(
  fc.property(fc.string(), fc.string(), fc.string(), (a, b, c) => {
    return (a + b) + c === a + (b + c);
  })
);

Core Concepts

Property Testing

Property-based testing verifies that a property holds true for all generated inputs, rather than testing specific examples.

/**
 * Create a synchronous property from arbitraries and a predicate
 */
function property<Ts extends [unknown, ...unknown[]]>(
  ...args: [...arbitraries: { [K in keyof Ts]: Arbitrary<Ts[K]> }, predicate: (...args: Ts) => boolean | void]
): IPropertyWithHooks<Ts>;

/**
 * Create an asynchronous property from arbitraries and an async predicate
 */
function asyncProperty<Ts extends [unknown, ...unknown[]]>(
  ...args: [...arbitraries: { [K in keyof Ts]: Arbitrary<Ts[K]> }, predicate: (...args: Ts) => Promise<boolean | void>]
): IAsyncPropertyWithHooks<Ts>;

Running Properties

/**
 * Run a property and throw on failure
 */
function assert<Ts>(
  property: IProperty<Ts> | IAsyncProperty<Ts>,
  params?: Parameters<Ts>
): void | Promise<void>;

/**
 * Run a property without throwing, returns detailed execution results
 */
function check<Ts>(
  property: IProperty<Ts> | IAsyncProperty<Ts>,
  params?: Parameters<Ts>
): RunDetails<Ts> | Promise<RunDetails<Ts>>;

Basic Usage:

import { assert, property, integer, string } from 'fast-check';

// Synchronous property
assert(
  property(integer(), string(), (num, str) => {
    return str.repeat(num).length === str.length * num;
  }),
  { numRuns: 1000 }
);

// Asynchronous property
await assert(
  asyncProperty(integer(), async (num) => {
    const result = await asyncOperation(num);
    return result > 0;
  })
);

Preconditions

Skip test cases that don't meet requirements:

/**
 * Add pre-condition checks inside property execution
 */
function pre(expectTruthy: boolean): asserts expectTruthy;

Usage:

import { assert, property, integer, pre } from 'fast-check';

assert(
  property(integer(), integer(), (a, b) => {
    pre(b !== 0); // Skip cases where b is 0
    return (a / b) * b === a;
  })
);

Arbitraries

Arbitraries are data generators that produce random values and shrink failing cases to minimal counterexamples.

Primitive Arbitraries

Generate basic JavaScript values: booleans, numbers, strings, dates.

function boolean(): Arbitrary<boolean>;
function integer(constraints?: IntegerConstraints): Arbitrary<number>;
function nat(constraints?: NatConstraints): Arbitrary<number>;
function float(constraints?: FloatConstraints): Arbitrary<number>;
function double(constraints?: DoubleConstraints): Arbitrary<number>;
function bigInt(constraints?: BigIntConstraints): Arbitrary<bigint>;
function string(constraints?: StringConstraints): Arbitrary<string>;
function date(constraints?: DateConstraints): Arbitrary<Date>;
function falsy(constraints?: FalsyContraints): Arbitrary<FalsyValue>;

Quick Examples:

import { integer, string, boolean, date } from 'fast-check';

// Integers in range
integer({ min: 0, max: 100 })

// Strings with length constraints
string({ minLength: 5, maxLength: 10 })

// Dates in range
date({ min: new Date('2020-01-01'), max: new Date('2025-12-31') })

Detailed Primitive Arbitraries

Collection Arbitraries

Generate arrays, sets, maps, tuples, and typed arrays.

function array<T>(arb: Arbitrary<T>, constraints?: ArrayConstraints): Arbitrary<T[]>;
function uniqueArray<T>(arb: Arbitrary<T>, constraints?: UniqueArrayConstraints<T>): Arbitrary<T[]>;
function set<T>(arb: Arbitrary<T>, constraints?: SetConstraints): Arbitrary<Set<T>>;
function map<K, V>(keyArb: Arbitrary<K>, valueArb: Arbitrary<V>, constraints?: MapConstraints): Arbitrary<Map<K, V>>;
function tuple<Ts extends unknown[]>(...arbs: { [K in keyof Ts]: Arbitrary<Ts[K]> }): Arbitrary<Ts>;
function subarray<T>(originalArray: T[], constraints?: SubarrayConstraints): Arbitrary<T[]>;

Quick Examples:

import { array, tuple, set, map } from 'fast-check';

// Arrays
array(integer(), { minLength: 1, maxLength: 10 })

// Tuples
tuple(string(), integer(), boolean())

// Sets
set(integer(), { minLength: 5 })

// Maps
map(string(), integer(), { maxKeys: 10 })

Detailed Collection Arbitraries

Object Arbitraries

Generate objects, records, dictionaries, and JSON.

function record<T, K extends keyof T = keyof T>(
  model: { [K in keyof T]: Arbitrary<T[K]> },
  constraints?: RecordConstraints<K>
): Arbitrary<RecordValue<T, K>>;
function object(constraints?: ObjectConstraints): Arbitrary<Record<string, unknown>>;
function dictionary<T>(
  keyArb: Arbitrary<string>,
  valueArb: Arbitrary<T>,
  constraints?: DictionaryConstraints
): Arbitrary<Record<string, T>>;
function json(constraints?: JsonSharedConstraints): Arbitrary<string>;
function jsonValue(constraints?: JsonSharedConstraints): Arbitrary<JsonValue>;

Quick Examples:

import { record, json, jsonValue } from 'fast-check';

// Typed records
record({
  id: string(),
  age: integer({ min: 0, max: 120 }),
  active: boolean()
}, { requiredKeys: ['id'] })

// JSON strings
json({ maxDepth: 3 })

// JSON values
jsonValue({ maxDepth: 3 })

Detailed Object Arbitraries

Web Arbitraries

Generate URLs, emails, IP addresses, domains, UUIDs.

function webUrl(constraints?: WebUrlConstraints): Arbitrary<string>;
function emailAddress(constraints?: EmailAddressConstraints): Arbitrary<string>;
function domain(constraints?: DomainConstraints): Arbitrary<string>;
function ipV4(): Arbitrary<string>;
function ipV6(): Arbitrary<string>;
function uuid(constraints?: UuidConstraints): Arbitrary<string>;
function ulid(): Arbitrary<string>;

Quick Examples:

import { webUrl, emailAddress, uuid } from 'fast-check';

// URLs
webUrl({ validSchemes: ['http', 'https'] })

// Email addresses
emailAddress()

// UUIDs
uuid({ version: 4 })

Detailed Web Arbitraries

Sampling and Statistics

Inspect generated values during development:

/**
 * Generate an array of sample values from an arbitrary
 */
function sample<Ts>(
  generator: IRawProperty<Ts> | Arbitrary<Ts>,
  params?: Parameters<Ts> | number
): Ts[];

/**
 * Gather and print statistics about generated values
 */
function statistics<Ts>(
  generator: IRawProperty<Ts> | Arbitrary<Ts>,
  classify: (v: Ts) => string | string[],
  params?: Parameters<Ts> | number
): void;

Usage:

import { sample, statistics, integer } from 'fast-check';

// Generate samples
const samples = sample(integer({ min: 0, max: 100 }), 10);
console.log(samples);

// Generate statistics
statistics(integer({ min: 0, max: 100 }), (n) => {
  if (n < 25) return 'low';
  if (n < 75) return 'medium';
  return 'high';
});

Configuration

Configure test execution parameters globally or per-property.

function configureGlobal(parameters: GlobalParameters): void;
function readConfigureGlobal(): GlobalParameters;
function resetConfigureGlobal(): void;

Common Parameters:

interface Parameters<T> {
  seed?: number;                    // Random seed for reproducibility
  numRuns?: number;                  // Number of test runs (default: 100)
  maxSkipsPerRun?: number;            // Max skipped tests before failing
  timeout?: number;                  // Timeout per run (ms)
  path?: string;                     // Path for replaying counterexample
  unbiased?: boolean;                // Disable bias towards edge cases
  verbose?: boolean | VerbosityLevel; // Verbosity level
  examples?: T[];                    // Custom examples to test first
  endOnFailure?: boolean;             // Stop on first failure
  reporter?: (runDetails: RunDetails<T>) => void;
  asyncReporter?: (runDetails: RunDetails<T>) => Promise<void>;
}

Detailed Configuration

Advanced Topics

Combinators

Compose and transform arbitraries to create custom generators.

function constant<T>(value: T): Arbitrary<T>;
function constantFrom<T>(...values: T[]): Arbitrary<T>;
function option<T, TNil = null>(arb: Arbitrary<T>, constraints?: OptionConstraints<TNil>): Arbitrary<T | TNil>;
function oneof<Ts extends MaybeWeightedArbitrary<unknown>[]>(...arbs: Ts | [OneOfConstraints, ...Ts]): Arbitrary<OneOfValue<Ts>>;
function letrec<T>(builder: LetrecTypedBuilder<T> | LetrecLooselyTypedBuilder<T>): LetrecValue<T>;
function memo<T>(builder: (maxDepth: number) => Arbitrary<T>): Memo<T>;

Detailed Combinators

Model-Based Testing

Test stateful systems using command sequences.

function commands<Model, Real, CheckAsync>(
  commandArbs: Arbitrary<AsyncCommand<Model, Real, CheckAsync>>[],
  constraints?: CommandsContraints
): Arbitrary<Iterable<AsyncCommand<Model, Real, CheckAsync>>>;

function asyncModelRun<Model, Real, CheckAsync, InitialModel>(
  s: ModelRunSetup<InitialModel, Real> | ModelRunAsyncSetup<InitialModel, Real>,
  cmds: Iterable<AsyncCommand<Model, Real, CheckAsync>>
): Promise<void>;

Detailed Model-Based Testing

Concurrency Testing

Detect race conditions by controlling async execution order.

function scheduler<TMetaData = unknown>(constraints?: SchedulerConstraints): Arbitrary<Scheduler<TMetaData>>;

function schedulerFor<TMetaData = unknown>(
  customOrderingOrConstraints?: number[] | SchedulerConstraints,
  constraintsOrUndefined?: SchedulerConstraints
): Scheduler<TMetaData> | ((strs: TemplateStringsArray, ...ordering: number[]) => Scheduler<TMetaData>);

Detailed Concurrency Testing

Core Types

// Property types
interface IProperty<Ts> { /* property definition */ }
interface IPropertyWithHooks<Ts> extends IProperty<Ts> {
  beforeEach(hookFunction: PropertyHookFunction): IPropertyWithHooks<Ts>;
  afterEach(hookFunction: PropertyHookFunction): IPropertyWithHooks<Ts>;
}
interface IAsyncProperty<Ts> { /* async property definition */ }
interface IAsyncPropertyWithHooks<Ts> extends IAsyncProperty<Ts> {
  beforeEach(hookFunction: AsyncPropertyHookFunction): IAsyncPropertyWithHooks<Ts>;
  afterEach(hookFunction: AsyncPropertyHookFunction): IAsyncPropertyWithHooks<Ts>;
}

// Result types
type RunDetails<Ts> =
  | RunDetailsSuccess<Ts>
  | RunDetailsFailureProperty<Ts>
  | RunDetailsFailureTooManySkips<Ts>
  | RunDetailsFailureInterrupted<Ts>;

interface RunDetailsSuccess<Ts> {
  failed: false;
  numRuns: number;
  numSkips: number;
  numShrinks: number;
  seed: number;
  counterexamplePath: string | null;
  error: null;
  failures: [];
  executionSummary: ExecutionTree<Ts>[];
  verbose: VerbosityLevel;
}

interface RunDetailsFailureProperty<Ts> {
  failed: true;
  numRuns: number;
  numSkips: number;
  numShrinks: number;
  seed: number;
  counterexamplePath: string;
  counterexample: Ts;
  error: string | Error | unknown;
  failures: Ts[];
  executionSummary: ExecutionTree<Ts>[];
  verbose: VerbosityLevel;
}

enum VerbosityLevel {
  None = 0,
  Verbose = 1,
  VeryVerbose = 2
}

// Error class
class PreconditionFailure extends Error {
  readonly interruptExecution: true;
  readonly footprint: string;
}

Base Classes

Arbitrary

The abstract base class for all arbitraries.

abstract class Arbitrary<T> {
  abstract generate(mrng: Random, biasFactor: number | undefined): Value<T>;
  canShrinkWithoutContext(value: unknown): value is T;
  shrink(value: T, context: unknown | undefined): Stream<Value<T>>;
  filter<U extends T>(refinement: (t: T) => t is U): Arbitrary<U>;
  filter(predicate: (t: T) => boolean): Arbitrary<T>;
  map<U>(mapper: (t: T) => U, unmapper?: (u: unknown) => T): Arbitrary<U>;
  chain<U>(chainer: (t: T) => Arbitrary<U>): Arbitrary<U>;
}

Detailed Base Classes and Utilities