Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

3 lat temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. <div align="center">
  2. <h1>jest-each</h1>
  3. Jest Parameterised Testing
  4. </div>
  5. <hr />
  6. [![version](https://img.shields.io/npm/v/jest-each.svg?style=flat-square)](https://www.npmjs.com/package/jest-each) [![downloads](https://img.shields.io/npm/dm/jest-each.svg?style=flat-square)](http://npm-stat.com/charts.html?package=jest-each&from=2017-03-21) [![MIT License](https://img.shields.io/npm/l/jest-each.svg?style=flat-square)](https://github.com/facebook/jest/blob/master/LICENSE)
  7. A parameterised testing library for [Jest](https://jestjs.io/) inspired by [mocha-each](https://github.com/ryym/mocha-each).
  8. 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.
  9. ## Features
  10. - `.test` to runs multiple tests with parameterised data
  11. - Also under the alias: `.it`
  12. - `.test.only` to only run the parameterised tests
  13. - Also under the aliases: `.it.only` or `.fit`
  14. - `.test.skip` to skip the parameterised tests
  15. - Also under the aliases: `.it.skip` or `.xit` or `.xtest`
  16. - `.describe` to runs test suites with parameterised data
  17. - `.describe.only` to only run the parameterised suite of tests
  18. - Also under the aliases: `.fdescribe`
  19. - `.describe.skip` to skip the parameterised suite of tests
  20. - Also under the aliases: `.xdescribe`
  21. - Asynchronous tests with `done`
  22. - Unique test titles with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args):
  23. - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format).
  24. - `%s`- String.
  25. - `%d`- Number.
  26. - `%i` - Integer.
  27. - `%f` - Floating point value.
  28. - `%j` - JSON.
  29. - `%o` - Object.
  30. - `%#` - Index of the test case.
  31. - `%%` - single percent sign ('%'). This does not consume an argument.
  32. - 🖖 Spock like data tables with [Tagged Template Literals](#tagged-template-literal-of-rows)
  33. ---
  34. - [Demo](#demo)
  35. - [Installation](#installation)
  36. - [Importing](#importing)
  37. - APIs
  38. - [Array of Rows](#array-of-rows)
  39. - [Usage](#usage)
  40. - [Tagged Template Literal of rows](#tagged-template-literal-of-rows)
  41. - [Usage](#usage-1)
  42. ## Demo
  43. #### Tests without jest-each
  44. ![Current jest tests](assets/default-demo.gif)
  45. #### Tests can be re-written with jest-each to:
  46. **`.test`**
  47. ![Current jest tests](assets/test-demo.gif)
  48. **`.test` with Tagged Template Literals**
  49. ![Current jest tests](assets/tagged-template-literal.gif)
  50. **`.describe`**
  51. ![Current jest tests](assets/describe-demo.gif)
  52. ## Installation
  53. `npm i --save-dev jest-each`
  54. `yarn add -D jest-each`
  55. ## Importing
  56. jest-each is a default export so it can be imported with whatever name you like.
  57. ```js
  58. // es6
  59. import each from 'jest-each';
  60. ```
  61. ```js
  62. // es5
  63. const each = require('jest-each');
  64. ```
  65. ## Array of rows
  66. ### API
  67. #### `each([parameters]).test(name, testFn)`
  68. ##### `each`:
  69. - parameters: `Array` of Arrays with the arguments that are passed into the `testFn` for each row
  70. - _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]]`
  71. ##### `.test`:
  72. - name: `String` the title of the `test`.
  73. - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args):
  74. - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format).
  75. - `%s`- String.
  76. - `%d`- Number.
  77. - `%i` - Integer.
  78. - `%f` - Floating point value.
  79. - `%j` - JSON.
  80. - `%o` - Object.
  81. - `%#` - Index of the test case.
  82. - `%%` - single percent sign ('%'). This does not consume an argument.
  83. - testFn: `Function` the test logic, this is the function that will receive the parameters of each row as function arguments
  84. #### `each([parameters]).describe(name, suiteFn)`
  85. ##### `each`:
  86. - parameters: `Array` of Arrays with the arguments that are passed into the `suiteFn` for each row
  87. - _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]]`
  88. ##### `.describe`:
  89. - name: `String` the title of the `describe`
  90. - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args):
  91. - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format).
  92. - `%s`- String.
  93. - `%d`- Number.
  94. - `%i` - Integer.
  95. - `%f` - Floating point value.
  96. - `%j` - JSON.
  97. - `%o` - Object.
  98. - `%#` - Index of the test case.
  99. - `%%` - single percent sign ('%'). This does not consume an argument.
  100. - 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
  101. ### Usage
  102. #### `.test(name, fn)`
  103. Alias: `.it(name, fn)`
  104. ```js
  105. each([[1, 1, 2], [1, 2, 3], [2, 1, 3]]).test(
  106. 'returns the result of adding %d to %d',
  107. (a, b, expected) => {
  108. expect(a + b).toBe(expected);
  109. },
  110. );
  111. ```
  112. #### `.test.only(name, fn)`
  113. Aliases: `.it.only(name, fn)` or `.fit(name, fn)`
  114. ```js
  115. each([[1, 1, 2], [1, 2, 3], [2, 1, 3]]).test.only(
  116. 'returns the result of adding %d to %d',
  117. (a, b, expected) => {
  118. expect(a + b).toBe(expected);
  119. },
  120. );
  121. ```
  122. #### `.test.skip(name, fn)`
  123. Aliases: `.it.skip(name, fn)` or `.xit(name, fn)` or `.xtest(name, fn)`
  124. ```js
  125. each([[1, 1, 2][(1, 2, 3)], [2, 1, 3]]).test.skip(
  126. 'returns the result of adding %d to %d',
  127. (a, b, expected) => {
  128. expect(a + b).toBe(expected);
  129. },
  130. );
  131. ```
  132. #### Asynchronous `.test(name, fn(done))`
  133. Alias: `.it(name, fn(done))`
  134. ```js
  135. each([['hello'], ['mr'], ['spy']]).test(
  136. 'gives 007 secret message: %s',
  137. (str, done) => {
  138. const asynchronousSpy = message => {
  139. expect(message).toBe(str);
  140. done();
  141. };
  142. callSomeAsynchronousFunction(asynchronousSpy)(str);
  143. },
  144. );
  145. ```
  146. #### `.describe(name, fn)`
  147. ```js
  148. each([[1, 1, 2], [1, 2, 3], [2, 1, 3]]).describe(
  149. '.add(%d, %d)',
  150. (a, b, expected) => {
  151. test(`returns ${expected}`, () => {
  152. expect(a + b).toBe(expected);
  153. });
  154. test('does not mutate first arg', () => {
  155. a + b;
  156. expect(a).toBe(a);
  157. });
  158. test('does not mutate second arg', () => {
  159. a + b;
  160. expect(b).toBe(b);
  161. });
  162. },
  163. );
  164. ```
  165. #### `.describe.only(name, fn)`
  166. Aliases: `.fdescribe(name, fn)`
  167. ```js
  168. each([[1, 1, 2], [1, 2, 3], [2, 1, 3]]).describe.only(
  169. '.add(%d, %d)',
  170. (a, b, expected) => {
  171. test(`returns ${expected}`, () => {
  172. expect(a + b).toBe(expected);
  173. });
  174. },
  175. );
  176. ```
  177. #### `.describe.skip(name, fn)`
  178. Aliases: `.xdescribe(name, fn)`
  179. ```js
  180. each([[1, 1, 2], [1, 2, 3], [2, 1, 3]]).describe.skip(
  181. '.add(%d, %d)',
  182. (a, b, expected) => {
  183. test(`returns ${expected}`, () => {
  184. expect(a + b).toBe(expected);
  185. });
  186. },
  187. );
  188. ```
  189. ---
  190. ## Tagged Template Literal of rows
  191. ### API
  192. #### `each[tagged template].test(name, suiteFn)`
  193. ```js
  194. each`
  195. a | b | expected
  196. ${1} | ${1} | ${2}
  197. ${1} | ${2} | ${3}
  198. ${2} | ${1} | ${3}
  199. `.test('returns $expected when adding $a to $b', ({a, b, expected}) => {
  200. expect(a + b).toBe(expected);
  201. });
  202. ```
  203. ##### `each` takes a tagged template string with:
  204. - First row of variable name column headings seperated with `|`
  205. - One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
  206. ##### `.test`:
  207. - 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
  208. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value`
  209. - testFn: `Function` the test logic, this is the function that will receive the parameters of each row as function arguments
  210. #### `each[tagged template].describe(name, suiteFn)`
  211. ```js
  212. each`
  213. a | b | expected
  214. ${1} | ${1} | ${2}
  215. ${1} | ${2} | ${3}
  216. ${2} | ${1} | ${3}
  217. `.describe('$a + $b', ({a, b, expected}) => {
  218. test(`returns ${expected}`, () => {
  219. expect(a + b).toBe(expected);
  220. });
  221. test('does not mutate first arg', () => {
  222. a + b;
  223. expect(a).toBe(a);
  224. });
  225. test('does not mutate second arg', () => {
  226. a + b;
  227. expect(b).toBe(b);
  228. });
  229. });
  230. ```
  231. ##### `each` takes a tagged template string with:
  232. - First row of variable name column headings seperated with `|`
  233. - One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
  234. ##### `.describe`:
  235. - 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
  236. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value`
  237. - 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
  238. ### Usage
  239. #### `.test(name, fn)`
  240. Alias: `.it(name, fn)`
  241. ```js
  242. each`
  243. a | b | expected
  244. ${1} | ${1} | ${2}
  245. ${1} | ${2} | ${3}
  246. ${2} | ${1} | ${3}
  247. `.test('returns $expected when adding $a to $b', ({a, b, expected}) => {
  248. expect(a + b).toBe(expected);
  249. });
  250. ```
  251. #### `.test.only(name, fn)`
  252. Aliases: `.it.only(name, fn)` or `.fit(name, fn)`
  253. ```js
  254. each`
  255. a | b | expected
  256. ${1} | ${1} | ${2}
  257. ${1} | ${2} | ${3}
  258. ${2} | ${1} | ${3}
  259. `.test.only('returns $expected when adding $a to $b', ({a, b, expected}) => {
  260. expect(a + b).toBe(expected);
  261. });
  262. ```
  263. #### `.test.skip(name, fn)`
  264. Aliases: `.it.skip(name, fn)` or `.xit(name, fn)` or `.xtest(name, fn)`
  265. ```js
  266. each`
  267. a | b | expected
  268. ${1} | ${1} | ${2}
  269. ${1} | ${2} | ${3}
  270. ${2} | ${1} | ${3}
  271. `.test.skip('returns $expected when adding $a to $b', ({a, b, expected}) => {
  272. expect(a + b).toBe(expected);
  273. });
  274. ```
  275. #### Asynchronous `.test(name, fn(done))`
  276. Alias: `.it(name, fn(done))`
  277. ```js
  278. each`
  279. str
  280. ${'hello'}
  281. ${'mr'}
  282. ${'spy'}
  283. `.test('gives 007 secret message: $str', ({str}, done) => {
  284. const asynchronousSpy = message => {
  285. expect(message).toBe(str);
  286. done();
  287. };
  288. callSomeAsynchronousFunction(asynchronousSpy)(str);
  289. });
  290. ```
  291. #### `.describe(name, fn)`
  292. ```js
  293. each`
  294. a | b | expected
  295. ${1} | ${1} | ${2}
  296. ${1} | ${2} | ${3}
  297. ${2} | ${1} | ${3}
  298. `.describe('$a + $b', ({a, b, expected}) => {
  299. test(`returns ${expected}`, () => {
  300. expect(a + b).toBe(expected);
  301. });
  302. test('does not mutate first arg', () => {
  303. a + b;
  304. expect(a).toBe(a);
  305. });
  306. test('does not mutate second arg', () => {
  307. a + b;
  308. expect(b).toBe(b);
  309. });
  310. });
  311. ```
  312. #### `.describe.only(name, fn)`
  313. Aliases: `.fdescribe(name, fn)`
  314. ```js
  315. each`
  316. a | b | expected
  317. ${1} | ${1} | ${2}
  318. ${1} | ${2} | ${3}
  319. ${2} | ${1} | ${3}
  320. `.describe.only('$a + $b', ({a, b, expected}) => {
  321. test(`returns ${expected}`, () => {
  322. expect(a + b).toBe(expected);
  323. });
  324. });
  325. ```
  326. #### `.describe.skip(name, fn)`
  327. Aliases: `.xdescribe(name, fn)`
  328. ```js
  329. each`
  330. a | b | expected
  331. ${1} | ${1} | ${2}
  332. ${1} | ${2} | ${3}
  333. ${2} | ${1} | ${3}
  334. `.describe.skip('$a + $b', ({a, b, expected}) => {
  335. test(`returns ${expected}`, () => {
  336. expect(a + b).toBe(expected);
  337. });
  338. });
  339. ```
  340. ## License
  341. MIT