jest-each
jest-each copied to clipboard
A parameterised testing library for Jest. https://www.npmjs.com/package/jest-each 🏃
jest-each has a new home over in core Jest 🎉
From Jest >=23 jest-each is available natively with test.each and describe.each see docs here
If you are using an older version of Jest I am still maintaining jest-each over in the core repo so you can still use jest-each in the exact same way as normal 😊
jest-each
Jest Parameterised TestingA 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
.testto runs multiple tests with parameterised data- Also under the alias:
.it
- Also under the alias:
.test.onlyto only run the parameterised tests- Also under the aliases:
.it.onlyor.fit
- Also under the aliases:
.test.skipto skip the parameterised tests- Also under the aliases:
.it.skipor.xitor.xtest
- Also under the aliases:
.describeto runs test suites with parameterised data.describe.onlyto only run the parameterised suite of tests- Also under the aliases:
.fdescribe
- Also under the aliases:
.describe.skipto skip the parameterised suite of tests- Also under the aliases:
.xdescribe
- Also under the aliases:
- Asynchronous tests with
done - Unique test titles with: sprintf
- 🖖 Spock like data tables with Tagged Template Literals
- Demo
- Installation
- Importing
- APIs
- Array of Rows
- Usage
- Tagged Template Literal of rows
- Usage
- Array of Rows
Demo
Tests without jest-each

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

.test with Tagged Template Literals

.describe

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');
Array of rows
API
each([parameters]).test(name, testFn)
each:
- parameters:
Arrayof Arrays with the arguments that are passed into thetestFnfor each row
.test:
- name:
Stringthe title of thetest, use%sin the name string to positionally inject parameter values into the test title - testFn:
Functionthe test logic, this is the function that will receive the parameters of each row as function arguments
each([parameters]).describe(name, suiteFn)
each:
- parameters:
Arrayof Arrays with the arguments that are passed into thesuiteFnfor each row
.describe:
- name:
Stringthe title of thedescribe, use%sin the name string to positionally inject parameter values into the suite title - suiteFn:
Functionthe suite oftest/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 %s to %s', (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 %s to %s', (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 %s to %s', (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 ', (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(%s, %s)', (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(%s, %s)', (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(%s, %s)', (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 seperated with
| - One or more subsequent rows of data supplied as template literal expressions using
${value}syntax.
.test:
- name:
Stringthe title of thetest, use$variablein the name string to inject test values into the test title from the tagged template expressions - testFn:
Functionthe 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 seperated with
| - One or more subsequent rows of data supplied as template literal expressions using
${value}syntax.
.describe:
- name:
Stringthe title of thetest, use$variablein the name string to inject test values into the test title from the tagged template expressions - suiteFn:
Functionthe suite oftest/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