CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-fast-check

Property based testing framework for JavaScript (like QuickCheck)

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/fast-check@4.5.x
Publish Source
CLI
Badge
tessl/npm-fast-check badge