mirror of
				https://kkgithub.com/actions/setup-python.git
				synced 2025-11-04 04:31:51 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			444 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			444 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
<div align="center">
 | 
						|
  <h1>jest-each</h1>
 | 
						|
  Jest Parameterised Testing
 | 
						|
</div>
 | 
						|
 | 
						|
<hr />
 | 
						|
 | 
						|
[](https://www.npmjs.com/package/jest-each) [](http://npm-stat.com/charts.html?package=jest-each&from=2017-03-21) [](https://github.com/facebook/jest/blob/master/LICENSE)
 | 
						|
 | 
						|
A parameterised testing library for [Jest](https://jestjs.io/) inspired by [mocha-each](https://github.com/ryym/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`
 | 
						|
- `.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](https://nodejs.org/api/util.html#util_util_format_format_args):
 | 
						|
  - `%p` - [pretty-format](https://www.npmjs.com/package/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.
 | 
						|
- 🖖 Spock like data tables with [Tagged Template Literals](#tagged-template-literal-of-rows)
 | 
						|
 | 
						|
---
 | 
						|
 | 
						|
- [Demo](#demo)
 | 
						|
- [Installation](#installation)
 | 
						|
- [Importing](#importing)
 | 
						|
- APIs
 | 
						|
  - [Array of Rows](#array-of-rows)
 | 
						|
    - [Usage](#usage)
 | 
						|
  - [Tagged Template Literal of rows](#tagged-template-literal-of-rows)
 | 
						|
    - [Usage](#usage-1)
 | 
						|
 | 
						|
## 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.
 | 
						|
 | 
						|
```js
 | 
						|
// es6
 | 
						|
import each from 'jest-each';
 | 
						|
```
 | 
						|
 | 
						|
```js
 | 
						|
// es5
 | 
						|
const each = require('jest-each');
 | 
						|
```
 | 
						|
 | 
						|
## 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](https://nodejs.org/api/util.html#util_util_format_format_args):
 | 
						|
    - `%p` - [pretty-format](https://www.npmjs.com/package/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.
 | 
						|
- 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](https://nodejs.org/api/util.html#util_util_format_format_args):
 | 
						|
    - `%p` - [pretty-format](https://www.npmjs.com/package/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.
 | 
						|
- suiteFn: `Function` the suite of `test`/`it`s 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)`
 | 
						|
 | 
						|
```js
 | 
						|
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);
 | 
						|
  },
 | 
						|
);
 | 
						|
```
 | 
						|
 | 
						|
#### `.test.only(name, fn)`
 | 
						|
 | 
						|
Aliases: `.it.only(name, fn)` or `.fit(name, fn)`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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);
 | 
						|
  },
 | 
						|
);
 | 
						|
```
 | 
						|
 | 
						|
#### Asynchronous `.test(name, fn(done))`
 | 
						|
 | 
						|
Alias: `.it(name, fn(done))`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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);
 | 
						|
    });
 | 
						|
  },
 | 
						|
);
 | 
						|
```
 | 
						|
 | 
						|
#### `.describe.only(name, fn)`
 | 
						|
 | 
						|
Aliases: `.fdescribe(name, fn)`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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: `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`
 | 
						|
- 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)`
 | 
						|
 | 
						|
```js
 | 
						|
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: `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`/`it`s 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)`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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))`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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)`
 | 
						|
 | 
						|
```js
 | 
						|
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
 |