or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

code-coverage.mdcommand-line-interface.mdindex.mdmemory-leak-detection.mdtest-execution.mdtest-organization.mdtypescript-integration.md
tile.json

test-organization.mddocs/

Test Organization

Core functionality for creating test scripts and organizing tests into experiments with setup/teardown hooks. This provides the fundamental building blocks for structuring test suites.

Capabilities

Script Creation

Creates a test script instance that provides the foundation for organizing and executing tests.

/**
 * Creates a test script with test organization capabilities
 * @param options - Optional configuration for script behavior
 * @returns Script instance with test organization methods
 */
function script(options?: ScriptOptions): Script;

interface ScriptOptions {
    /** Determines if execution should be delayed until CLI runs explicitly (default: true) */
    schedule?: boolean;
    /** CLI configuration options */
    cli?: CliOptions;
}

interface Script {
    experiment: Experiment;
    describe: Experiment;  // Alias for experiment
    suite: Experiment;     // Alias for experiment
    test: Test;
    it: Test;              // Alias for test
    before: Setup;
    after: Setup;
    beforeEach: Setup;
    afterEach: Setup;
}

Usage Examples:

const Lab = require('@hapi/lab');

// Basic script creation
const lab = exports.lab = Lab.script();

// Script with options
const lab = exports.lab = Lab.script({ 
    schedule: false  // Don't auto-execute
});

Experiment Definition

Creates test experiments (suites) for organizing related tests with shared setup and teardown.

/**
 * Creates a test experiment for organizing related tests
 * @param title - Descriptive name for the experiment
 * @param content - Function containing tests and sub-experiments
 */
experiment(title: string, content: () => void): void;

/**
 * Creates a test experiment with options
 * @param title - Descriptive name for the experiment
 * @param options - Experiment configuration (excluding plan)
 * @param content - Function containing tests and sub-experiments
 */
experiment(title: string, options: Omit<TestOptions, 'plan'>, content: () => void): void;

interface Experiment {
    (title: string, content: () => void): void;
    (title: string, options: Omit<TestOptions, 'plan'>, content: () => void): void;
    /** Run only this experiment, skipping all others */
    only(title: string, content: () => void): void;
    only(title: string, options: Omit<TestOptions, 'plan'>, content: () => void): void;
    /** Skip this experiment during execution */
    skip(title: string, content: () => void): void;
    skip(title: string, options: Omit<TestOptions, 'plan'>, content: () => void): void;
}

Usage Examples:

// Basic experiment
experiment('User authentication', () => {
    // tests go here
});

// Experiment with timeout
experiment('Database operations', { timeout: 5000 }, () => {
    // longer-running tests
});

// Skip experiment
experiment.skip('Broken feature', () => {
    // temporarily disabled tests
});

// Run only this experiment
experiment.only('Debug this', () => {
    // focus on specific tests
});

Test Definition

Defines individual test cases within experiments.

/**
 * Defines an individual test case
 * @param title - Descriptive name for the test
 * @param testFn - Test function to execute
 */
test(title: string, testFn: Action): void;

/**
 * Defines a test case with options
 * @param title - Descriptive name for the test
 * @param options - Test configuration options
 * @param testFn - Test function to execute
 */
test(title: string, options: TestOptions, testFn: Action): void;

interface Test {
    (title: string, test: Action): void;
    (title: string, options: TestOptions, test: Action): void;
    /** Run only this test, skipping all others */
    only(title: string, test: Action): void;
    only(title: string, options: TestOptions, test: Action): void;
    /** Skip this test during execution */
    skip(title: string, test: Action): void;
    skip(title: string, options: TestOptions, test: Action): void;
}

interface Action {
    /** Test function receiving flags for utilities and context */
    (flags: Flags): Promise<any> | void;
}

Usage Examples:

// Synchronous test
test('validates user input', () => {
    expect(validateEmail('test@example.com')).to.be.true();
});

// Asynchronous test
test('fetches user data', async () => {
    const user = await getUserById(123);
    expect(user.name).to.equal('John Doe');
});

// Test with options
test('complex operation', { timeout: 10000, plan: 3 }, (flags) => {
    // Test expecting exactly 3 assertions with 10s timeout
});

// Using test flags
test('cleanup test', (flags) => {
    flags.onCleanup = () => cleanupDatabase();
    // test implementation
});

Setup and Teardown Hooks

Provides setup and teardown functionality for experiments with flexible timing options.

/**
 * Runs setup function before all tests in the current experiment
 * @param action - Setup function to execute
 */
before(action: Action): void;

/**
 * Runs setup function with options before all tests
 * @param options - Setup configuration
 * @param action - Setup function to execute
 */
before(options: TestOptions, action: Action): void;

/**
 * Runs teardown function after all tests in the current experiment
 * @param action - Teardown function to execute
 */
after(action: Action): void;

/**
 * Runs teardown function with options after all tests
 * @param options - Teardown configuration
 * @param action - Teardown function to execute
 */
after(options: TestOptions, action: Action): void;

/**
 * Runs setup function before each test in the current experiment
 * @param action - Setup function to execute
 */
beforeEach(action: Action): void;

/**
 * Runs setup function with options before each test
 * @param options - Setup configuration
 * @param action - Setup function to execute
 */
beforeEach(options: TestOptions, action: Action): void;

/**
 * Runs teardown function after each test in the current experiment
 * @param action - Teardown function to execute
 */
afterEach(action: Action): void;

/**
 * Runs teardown function with options after each test
 * @param options - Teardown configuration
 * @param action - Teardown function to execute
 */
afterEach(options: TestOptions, action: Action): void;

interface Setup {
    (action: Action): void;
    (options: TestOptions, action: Action): void;
}

Usage Examples:

experiment('Database tests', () => {

    before(async () => {
        await setupDatabase();
    });

    after(async () => {
        await cleanupDatabase();
    });

    beforeEach(() => {
        resetTestData();
    });

    afterEach(() => {
        clearCache();
    });

    // Setup with timeout
    before({ timeout: 30000 }, async () => {
        await longRunningSetup();
    });

    test('user creation', () => {
        // test implementation
    });
});

Test Context and Utilities

Flags Interface

The Flags interface provides utilities and context available to test functions and setup/teardown hooks.

interface Flags {
    /** Shared object for passing data between setup, tests, and teardown */
    readonly context: Record<string, any>;
    
    /** 
     * Wraps a function to require a specific number of invocations
     * @param func - Function to wrap
     * @param count - Required number of calls
     * @returns Wrapped function that tracks call count
     */
    mustCall<T extends (...args: any[]) => any>(func: T, count: number): T;
    
    /** 
     * Adds notes to the test log for console reporter output
     * @param note - String to include in console output
     */
    note(note: string): void;
    
    /** Cleanup function executed after test completion */
    onCleanup?: Action;
    
    /** Override for global exception handling */
    onUncaughtException?: ErrorHandler;
    
    /** Override for global rejection handling */
    onUnhandledRejection?: ErrorHandler;
}

Usage Examples:

test('callback verification', (flags) => {
    const callback = flags.mustCall((result) => {
        expect(result).to.equal('success');
    }, 2); // Must be called exactly twice
    
    asyncFunction(callback);
    anotherAsyncFunction(callback);
});

test('with context', (flags) => {
    flags.context.userId = 123;
    flags.note('Testing with user ID: 123');
    
    flags.onCleanup = () => {
        cleanupUser(flags.context.userId);
    };
});

Configuration Options

Test Options

Configuration options available for tests, experiments, and setup/teardown hooks.

interface TestOptions {
    /** Skip this test/experiment during execution */
    skip?: boolean;
    
    /** Run only this test/experiment, skipping all others */
    only?: boolean;
    
    /** Override default timeout in milliseconds (default: 2000) */
    timeout?: number;
    
    /** Expected number of assertions this test must execute */
    plan?: number;
    
    /** Retry failed tests (true for default retries, number for specific count) */
    retry?: number | boolean;
}