lab

Node test utility.

Latest Version: 26.0.0
hapi-family
Installation:

npm: npm install @hapi/lab

yarn: yarn add @hapi/lab

Module Status:
Version License Node Dependencies CI
26.0.0
hapi helmet github logo
BSD 16, 18, 20 Dependency Status Build Status
25.3.2
hapi helmet github logo
BSD 16, 18, 20 Dependency Status Build Status
24.7.1
hapi helmet github logo
BSD 16, 18, 20 Dependency Status Build Status

Introduction

lab is a simple test utility for Node.js. Unlike other test utilities, lab uses only async/await features and includes everything you should expect from a modern Node.js test utility. Our goal with lab is to keep the execution engine as simple as possible, and not try to build an extensible framework.

lab works best with the code assertion library but can be used with any assertion library that throws an error when a condition isn't met.

Usage

By default, lab loads all the '*.js|cjs|mjs' files inside the local 'test' directory and executes the tests found. To use different directories or files, pass the file or directories as arguments:

$ lab unit.js

Test files must require the lab module, and export a test script:

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

const { expect } = Code;
const { it } = exports.lab = Lab.script();

it('returns true when 1 + 1 equals 2', () => {

    expect(1 + 1).to.equal(2);
});

Or

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

const { expect } = Code;
const lab = exports.lab = Lab.script();

lab.test('returns true when 1 + 1 equals 2', () => {

    expect(1 + 1).to.equal(2);
});

If a test is performing an asynchronous operation then it should use the async / await keywords or return a Promise. For example:

lab.test('config file has correct value', async () => {

    const file = await fs.readFile('config');
    expect(file.toString()).to.contain('something');
});

Tests can be organized into experiments:

lab.experiment('math', () => {

    lab.test('returns true when 1 + 1 equals 2', () => {

        expect(1 + 1).to.equal(2);
    });
});

If you need to perform some setup operations before or after executing the tests inside an experiment, the before() and after() methods can be used. To execute code before or after each test in an experiment, use beforeEach() and afterEach().

lab.experiment('math', () => {

    lab.before(() => {

        return new Promise((resolve) => {

            // Wait 1 second
            setTimeout(() => {

                resolve();
            }, 1000);
        });
    });

    lab.beforeEach(() => {

        // Run before every single test
    });

    lab.test('returns true when 1 + 1 equals 2', () => {

        expect(1 + 1).to.equal(2);
    });
});

test(), before(), beforeEach(), after() and afterEach() also support returning promises just as tests do:

lab.experiment('math', () => {

    lab.before(() => {

        return aFunctionReturningAPromise();
    });

    lab.test('returns true when 1 + 1 equals 2', () => {

        return aFunctionReturningAPromise()
            .then((aValue) => {

                expect(aValue).to.equal(expectedValue);
            });
    });
});

Both test() and experiment() accept an optional options argument which must be an object with the following optional keys:

  • timeout - set a test or experiment specific timeout in milliseconds. Defaults to the global timeout (2000ms or the value of -m).
  • skip - skip execution. When used on an experiment, all children will be skipped - even if they are marked with only.
  • only - marks all other tests or experiments with skip.

You can also append .only(…) or .skip(…) to test and experiment instead of using options:

lab.experiment('with only', () => {

    lab.test.only('only this test will run', () => {

        expect(1 + 1).to.equal(2);
    });

    lab.test('another test that will not be executed', () => {});
});