Have ideas to improve npm?Join in the discussion! »

    jest-each
    TypeScript icon, indicating that this package has built-in type declarations

    27.0.2 • Public • Published

    jest-each

    Jest Parameterised Testing

    version downloads MIT License

    A parameterised testing library for Jest inspired by mocha-each.

    jest-each allows you to provide multiple arguments to your test/describe which results in the test/suite being run once per row of parameters.

    Features

    • .test to runs multiple tests with parameterised data
      • Also under the alias: .it
    • .test.only to only run the parameterised tests
      • Also under the aliases: .it.only or .fit
    • .test.skip to skip the parameterised tests
      • Also under the aliases: .it.skip or .xit or .xtest
    • .test.concurrent
      • Also under the alias: .it.concurrent
    • .test.concurrent.only
      • Also under the alias: .it.concurrent.only
    • .test.concurrent.skip
      • Also under the alias: .it.concurrent.skip
    • .describe to runs test suites with parameterised data
    • .describe.only to only run the parameterised suite of tests
      • Also under the aliases: .fdescribe
    • .describe.skip to skip the parameterised suite of tests
      • Also under the aliases: .xdescribe
    • Asynchronous tests with done
    • Unique test titles with printf formatting:
      • %p - pretty-format.
      • %s- String.
      • %d- Number.
      • %i - Integer.
      • %f - Floating point value.
      • %j - JSON.
      • %o - Object.
      • %# - Index of the test case.
      • %% - single percent sign ('%'). This does not consume an argument.
    • Unique test titles by injecting properties of test case object
    • 🖖 Spock like data tables with Tagged Template Literals

    Demo

    Tests without jest-each

    Current jest tests

    Tests can be re-written with jest-each to:

    .test

    Current jest tests

    .test with Tagged Template Literals

    Current jest tests

    .describe

    Current jest tests

    Installation

    npm i --save-dev jest-each

    yarn add -D jest-each

    Importing

    jest-each is a default export so it can be imported with whatever name you like.

    // es6
    import each from 'jest-each';
    // es5
    const each = require('jest-each').default;

    Array of rows

    API

    each([parameters]).test(name, testFn)

    each:
    • parameters: Array of Arrays with the arguments that are passed into the testFn for each row
      • Note If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. [1, 2, 3] -> [[1], [2], [3]]
    .test:
    • name: String the title of the test.
      • Generate unique test titles by positionally injecting parameters with printf formatting:
        • %p - pretty-format.
        • %s- String.
        • %d- Number.
        • %i - Integer.
        • %f - Floating point value.
        • %j - JSON.
        • %o - Object.
        • %# - Index of the test case.
        • %% - single percent sign ('%'). This does not consume an argument.
      • Or generate unique test titles by injecting properties of test case object with $variable
        • To inject nested object values use you can supply a keyPath i.e. $variable.path.to.value
        • You can use $# to inject the index of the test case
        • You cannot use $variable with the printf formatting except for %%
    • testFn: Function the test logic, this is the function that will receive the parameters of each row as function arguments

    each([parameters]).describe(name, suiteFn)

    each:
    • parameters: Array of Arrays with the arguments that are passed into the suiteFn for each row
      • Note If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. [1, 2, 3] -> [[1], [2], [3]]
    .describe:
    • name: String the title of the describe
      • Generate unique test titles by positionally injecting parameters with printf formatting:
        • %p - pretty-format.
        • %s- String.
        • %d- Number.
        • %i - Integer.
        • %f - Floating point value.
        • %j - JSON.
        • %o - Object.
        • %# - Index of the test case.
        • %% - single percent sign ('%'). This does not consume an argument.
      • Or generate unique test titles by injecting properties of test case object with $variable
        • To inject nested object values use you can supply a keyPath i.e. $variable.path.to.value
        • You can use $# to inject the index of the test case
        • You cannot use $variable with the printf formatting except for %%
    • suiteFn: Function the suite of test/its to be ran, this is the function that will receive the parameters in each row as function arguments

    Usage

    .test(name, fn)

    Alias: .it(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).test('returns the result of adding %d to %d', (a, b, expected) => {
      expect(a + b).toBe(expected);
    });
    each([
      {a: 1, b: 1, expected: 2},
      {a: 1, b: 2, expected: 3},
      {a: 2, b: 1, expected: 3},
    ]).test('returns the result of adding $a to $b', ({a, b, expected}) => {
      expect(a + b).toBe(expected);
    });

    .test.only(name, fn)

    Aliases: .it.only(name, fn) or .fit(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).test.only('returns the result of adding %d to %d', (a, b, expected) => {
      expect(a + b).toBe(expected);
    });

    .test.skip(name, fn)

    Aliases: .it.skip(name, fn) or .xit(name, fn) or .xtest(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).test.skip('returns the result of adding %d to %d', (a, b, expected) => {
      expect(a + b).toBe(expected);
    });

    .test.concurrent(name, fn)

    Aliases: .it.concurrent(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).test.concurrent(
      'returns the result of adding %d to %d',
      (a, b, expected) => {
        expect(a + b).toBe(expected);
      },
    );

    .test.concurrent.only(name, fn)

    Aliases: .it.concurrent.only(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).test.concurrent.only(
      'returns the result of adding %d to %d',
      (a, b, expected) => {
        expect(a + b).toBe(expected);
      },
    );

    .test.concurrent.skip(name, fn)

    Aliases: .it.concurrent.skip(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).test.concurrent.skip(
      'returns the result of adding %d to %d',
      (a, b, expected) => {
        expect(a + b).toBe(expected);
      },
    );

    Asynchronous .test(name, fn(done))

    Alias: .it(name, fn(done))

    each([['hello'], ['mr'], ['spy']]).test(
      'gives 007 secret message: %s',
      (str, done) => {
        const asynchronousSpy = message => {
          expect(message).toBe(str);
          done();
        };
        callSomeAsynchronousFunction(asynchronousSpy)(str);
      },
    );

    .describe(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).describe('.add(%d, %d)', (a, b, expected) => {
      test(`returns ${expected}`, () => {
        expect(a + b).toBe(expected);
      });
    
      test('does not mutate first arg', () => {
        a + b;
        expect(a).toBe(a);
      });
    
      test('does not mutate second arg', () => {
        a + b;
        expect(b).toBe(b);
      });
    });
    each([
      {a: 1, b: 1, expected: 2},
      {a: 1, b: 2, expected: 3},
      {a: 2, b: 1, expected: 3},
    ]).describe('.add($a, $b)', ({a, b, expected}) => {
      test(`returns ${expected}`, () => {
        expect(a + b).toBe(expected);
      });
    
      test('does not mutate first arg', () => {
        a + b;
        expect(a).toBe(a);
      });
    
      test('does not mutate second arg', () => {
        a + b;
        expect(b).toBe(b);
      });
    });

    .describe.only(name, fn)

    Aliases: .fdescribe(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).describe.only('.add(%d, %d)', (a, b, expected) => {
      test(`returns ${expected}`, () => {
        expect(a + b).toBe(expected);
      });
    });

    .describe.skip(name, fn)

    Aliases: .xdescribe(name, fn)

    each([
      [1, 1, 2],
      [1, 2, 3],
      [2, 1, 3],
    ]).describe.skip('.add(%d, %d)', (a, b, expected) => {
      test(`returns ${expected}`, () => {
        expect(a + b).toBe(expected);
      });
    });

    Tagged Template Literal of rows

    API

    each[tagged template].test(name, suiteFn)

    each`
      a    | b    | expected
      ${1} | ${1} | ${2}
      ${1} | ${2} | ${3}
      ${2} | ${1} | ${3}
    `.test('returns $expected when adding $a to $b', ({a, b, expected}) => {
      expect(a + b).toBe(expected);
    });
    each takes a tagged template string with:
    • First row of variable name column headings separated with |
    • One or more subsequent rows of data supplied as template literal expressions using ${value} syntax.
    .test:
    • name: String the title of the test, use $variable in the name string to inject test values into the test title from the tagged template expressions
      • To inject nested object values use you can supply a keyPath i.e. $variable.path.to.value
      • You can use $# to inject the index of the table row.
    • testFn: Function the test logic, this is the function that will receive the parameters of each row as function arguments

    each[tagged template].describe(name, suiteFn)

    each`
      a    | b    | expected
      ${1} | ${1} | ${2}
      ${1} | ${2} | ${3}
      ${2} | ${1} | ${3}
    `.describe('$a + $b', ({a, b, expected}) => {
      test(`returns ${expected}`, () => {
        expect(a + b).toBe(expected);
      });
    
      test('does not mutate first arg', () => {
        a + b;
        expect(a).toBe(a);
      });
    
      test('does not mutate second arg', () => {
        a + b;
        expect(b).toBe(b);
      });
    });
    each takes a tagged template string with:
    • First row of variable name column headings separated with |
    • One or more subsequent rows of data supplied as template literal expressions using ${value} syntax.
    .describe:
    • name: String the title of the test, use $variable in the name string to inject test values into the test title from the tagged template expressions
      • To inject nested object values use you can supply a keyPath i.e. $variable.path.to.value
    • suiteFn: Function the suite of test/its to be ran, this is the function that will receive the parameters in each row as function arguments

    Usage

    .test(name, fn)

    Alias: .it(name, fn)

    each`
      a    | b    | expected
      ${1} | ${1} | ${2}
      ${1} | ${2} | ${3}
      ${2} | ${1} | ${3}
    `.test('returns $expected when adding $a to $b', ({a, b, expected}) => {
      expect(a + b).toBe(expected);
    });

    .test.only(name, fn)

    Aliases: .it.only(name, fn) or .fit(name, fn)

    each`
      a    | b    | expected
      ${1} | ${1} | ${2}
      ${1} | ${2} | ${3}
      ${2} | ${1} | ${3}
    `.test.only('returns $expected when adding $a to $b', ({a, b, expected}) => {
      expect(a + b).toBe(expected);
    });

    .test.skip(name, fn)

    Aliases: .it.skip(name, fn) or .xit(name, fn) or .xtest(name, fn)

    each`
      a    | b    | expected
      ${1} | ${1} | ${2}
      ${1} | ${2} | ${3}
      ${2} | ${1} | ${3}
    `.test.skip('returns $expected when adding $a to $b', ({a, b, expected}) => {
      expect(a + b).toBe(expected);
    });

    Asynchronous .test(name, fn(done))

    Alias: .it(name, fn(done))

    each`
      str
      ${'hello'}
      ${'mr'}
      ${'spy'}
    `.test('gives 007 secret message: $str', ({str}, done) => {
      const asynchronousSpy = message => {
        expect(message).toBe(str);
        done();
      };
      callSomeAsynchronousFunction(asynchronousSpy)(str);
    });

    .describe(name, fn)

    each`
      a    | b    | expected
      ${1} | ${1} | ${2}
      ${1} | ${2} | ${3}
      ${2} | ${1} | ${3}
    `.describe('$a + $b', ({a, b, expected}) => {
      test(`returns ${expected}`, () => {
        expect(a + b).toBe(expected);
      });
    
      test('does not mutate first arg', () => {
        a + b;
        expect(a).toBe(a);
      });
    
      test('does not mutate second arg', () => {
        a + b;
        expect(b).toBe(b);
      });
    });

    .describe.only(name, fn)

    Aliases: .fdescribe(name, fn)

    each`
      a    | b    | expected
      ${1} | ${1} | ${2}
      ${1} | ${2} | ${3}
      ${2} | ${1} | ${3}
    `.describe.only('$a + $b', ({a, b, expected}) => {
      test(`returns ${expected}`, () => {
        expect(a + b).toBe(expected);
      });
    });

    .describe.skip(name, fn)

    Aliases: .xdescribe(name, fn)

    each`
      a    | b    | expected
      ${1} | ${1} | ${2}
      ${1} | ${2} | ${3}
      ${2} | ${1} | ${3}
    `.describe.skip('$a + $b', ({a, b, expected}) => {
      test(`returns ${expected}`, () => {
        expect(a + b).toBe(expected);
      });
    });

    License

    MIT

    Install

    npm i jest-each

    DownloadsWeekly Downloads

    10,101,984

    Version

    27.0.2

    License

    MIT

    Unpacked Size

    39.9 kB

    Total Files

    15

    Last publish

    Collaborators

    • avatar
    • avatar
    • avatar
    • avatar
    • avatar
    • avatar