UNPKG

43.6 kBMarkdownView Raw
1# [![AVA](media/header.png)](https://ava.li)
2
3> Futuristic test runner
4
5[![Build Status: Linux](https://travis-ci.org/avajs/ava.svg?branch=master)](https://travis-ci.org/avajs/ava) [![Build status: Windows](https://ci.appveyor.com/api/projects/status/e7v91mu2m5x48ehx/branch/master?svg=true)](https://ci.appveyor.com/project/ava/ava/branch/master) [![Coverage Status](https://coveralls.io/repos/github/avajs/ava/badge.svg?branch=master)](https://coveralls.io/github/avajs/ava?branch=master) [![Dependency Status](https://dependencyci.com/github/avajs/ava/badge)](https://dependencyci.com/github/avajs/ava) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) [![Gitter](https://badges.gitter.im/join_chat.svg)](https://gitter.im/avajs/ava) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs)
6
7Even though JavaScript is single-threaded, IO in Node.js can happen in parallel due to its async nature. AVA takes advantage of this and runs your tests concurrently, which is especially beneficial for IO heavy tests. In addition, test files are run in parallel as separate processes, giving you even better performance and an isolated environment for each test file. [Switching](https://github.com/sindresorhus/pageres/commit/663be15acb3dd2eb0f71b1956ef28c2cd3fdeed0) from Mocha to AVA in Pageres brought the test time down from 31 to 11 seconds. Having tests run concurrently forces you to write atomic tests, meaning tests don't depend on global state or the state of other tests, which is a great thing!
8
9![](media/mini-reporter.gif)
10
11*Read our [contributing guide](contributing.md) if you're looking to contribute (issues/PRs/etc).*
12
13Follow the [AVA Twitter account](https://twitter.com/ava__js) for updates.
14
15Translations: [Español](https://github.com/avajs/ava-docs/blob/master/es_ES/readme.md), [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/readme.md), [Italiano](https://github.com/avajs/ava-docs/blob/master/it_IT/readme.md), [日本語](https://github.com/avajs/ava-docs/blob/master/ja_JP/readme.md), [한국어](https://github.com/avajs/ava-docs/blob/master/ko_KR/readme.md), [Português](https://github.com/avajs/ava-docs/blob/master/pt_BR/readme.md), [Русский](https://github.com/avajs/ava-docs/blob/master/ru_RU/readme.md), [简体中文](https://github.com/avajs/ava-docs/blob/master/zh_CN/readme.md)
16
17
18## Contents
19
20- [Usage](#usage)
21- [CLI Usage](#cli)
22- [Debugging](#debugging)
23- [Reporters](#reporters)
24- [Configuration](#configuration)
25- [Documentation](#documentation)
26- [API](#api)
27- [Assertions](#assertions)
28- [Snapshot testing](#snapshot-testing)
29- [Tips](#tips)
30- [FAQ](#faq)
31- [Recipes](#recipes)
32- [Support](#support)
33- [Related](#related)
34- [Links](#links)
35- [Team](#team)
36
37
38## Why AVA?
39
40- Minimal and fast
41- Simple test syntax
42- Runs tests concurrently
43- Enforces writing atomic tests
44- No implicit globals
45- Includes TypeScript & Flow type definitions
46- [Magic assert](#magic-assert)
47- [Isolated environment for each test file](#process-isolation)
48- [Write your tests in ES2017](#es2017-support)
49- [Promise support](#promise-support)
50- [Generator function support](#generator-function-support)
51- [Async function support](#async-function-support)
52- [Observable support](#observable-support)
53- [Enhanced assertion messages](#enhanced-assertion-messages)
54- [TAP reporter](#tap-reporter)
55- [Automatic migration from other test runners](https://github.com/avajs/ava-codemods#migrating-to-ava)
56
57
58## Test syntax
59
60```js
61import test from 'ava';
62
63test(t => {
64 t.deepEqual([1, 2], [1, 2]);
65});
66```
67
68## Usage
69
70### Add AVA to your project
71
72Install AVA globally and run it with `--init` to add AVA to your `package.json`.
73
74
75```console
76$ npm install --global ava
77$ ava --init
78```
79
80If you prefer using Yarn:
81
82```console
83$ yarn global add ava
84$ ava --init
85```
86
87Your `package.json` will then look like this:
88
89```json
90{
91 "name": "awesome-package",
92 "scripts": {
93 "test": "ava"
94 },
95 "devDependencies": {
96 "ava": "^0.20.0"
97 }
98}
99```
100
101Any arguments passed after `--init` are added as config to `package.json`.
102
103#### Manual installation
104
105You can also install AVA directly:
106
107```console
108$ npm install --save-dev ava
109```
110
111Alternatively using Yarn:
112
113```console
114$ yarn add --dev ava
115```
116
117You'll have to configure the `test` script in your `package.json` to use `ava` (see above).
118
119### Create your test file
120
121Create a file named `test.js` in the project root directory:
122
123```js
124import test from 'ava';
125
126test('foo', t => {
127 t.pass();
128});
129
130test('bar', async t => {
131 const bar = Promise.resolve('bar');
132
133 t.is(await bar, 'bar');
134});
135```
136
137### Run it
138
139```console
140$ npm test
141```
142
143### Watch it
144
145```console
146$ npm test -- --watch
147```
148
149AVA comes with an intelligent watch mode. [Learn more in its recipe](docs/recipes/watch-mode.md).
150
151## CLI
152
153```console
154$ ava --help
155
156 Usage
157 ava [<file|directory|glob> ...]
158
159 Options
160 --init Add AVA to your project
161 --fail-fast Stop after first test failure
162 --serial, -s Run tests serially
163 --tap, -t Generate TAP output
164 --verbose, -v Enable verbose output
165 --no-cache Disable the transpiler cache
166 --no-power-assert Disable Power Assert
167 --color Force color output
168 --no-color Disable color output
169 --match, -m Only run tests with matching title (Can be repeated)
170 --watch, -w Re-run tests when tests and source files change
171 --timeout, -T Set global timeout
172 --concurrency, -c Max number of test files running at the same time (Default: CPU cores)
173 --update-snapshots, -u Update snapshots
174
175 Examples
176 ava
177 ava test.js test2.js
178 ava test-*.js
179 ava test
180 ava --init
181 ava --init foo.js
182
183 Default patterns when no arguments:
184 test.js test-*.js test/**/*.js **/__tests__/**/*.js **/*.test.js
185```
186
187*Note that the CLI will use your local install of AVA when available, even when run globally.*
188
189Directories are recursed, with all `*.js` files being treated as test files. Directories named `fixtures`, `helpers` and `node_modules` are *always* ignored. So are files starting with `_` which allows you to place helpers in the same directory as your test files.
190
191When using `npm test`, you can pass positional arguments directly `npm test test2.js`, but flags needs to be passed like `npm test -- --verbose`.
192
193
194## Debugging
195
196AVA runs tests in child processes, so to debug tests, you need to do this workaround:
197
198```console
199$ node --inspect node_modules/ava/profile.js some/test/file.js
200```
201
202### Debugger-specific tips
203
204- [Chrome DevTools](docs/recipes/debugging-with-chrome-devtools.md)
205- [WebStorm](docs/recipes/debugging-with-webstorm.md)
206- [Visual Studio Code](docs/recipes/debugging-with-vscode.md)
207
208
209## Reporters
210
211### Mini-reporter
212
213The mini-reporter is the default reporter.
214
215<img src="media/mini-reporter.gif" width="460">
216
217### Verbose reporter
218
219Use the `--verbose` flag to enable the verbose reporter. This is always used in CI environments unless the [TAP reporter](#tap-reporter) is enabled.
220
221<img src="media/verbose-reporter.png" width="294">
222
223### TAP reporter
224
225AVA supports the TAP format and thus is compatible with [any TAP reporter](https://github.com/sindresorhus/awesome-tap#reporters). Use the `--tap` flag to enable TAP output.
226
227```console
228$ ava --tap | tap-nyan
229```
230
231<img src="media/tap-reporter.png" width="420">
232
233Please note that the TAP reporter is unavailable when using [watch mode](#watch-it).
234
235### Magic assert
236
237AVA adds code excerpts and clean diffs for actual and expected values. If values in the assertion are objects or arrays, only a diff is displayed, to remove the noise and focus on the problem. The diff is syntax-highlighted too! If you are comparing strings, both single and multi line, AVA displays a different kind of output, highlighting the added or missing characters.
238
239![](media/magic-assert-combined.png)
240
241### Clean stack traces
242
243AVA automatically removes unrelated lines in stack traces, allowing you to find the source of an error much faster, as seen above.
244
245
246## Configuration
247
248All of the CLI options can be configured in the `ava` section of your `package.json`. This allows you to modify the default behavior of the `ava` command, so you don't have to repeatedly type the same options on the command prompt.
249
250```json
251{
252 "ava": {
253 "files": [
254 "my-test-folder/*.js",
255 "!**/not-this-file.js"
256 ],
257 "source": [
258 "**/*.{js,jsx}",
259 "!dist/**/*"
260 ],
261 "match": [
262 "*oo",
263 "!foo"
264 ],
265 "concurrency": 5,
266 "failFast": true,
267 "failWithoutAssertions": false,
268 "tap": true,
269 "powerAssert": false,
270 "require": [
271 "babel-register"
272 ],
273 "babel": "inherit"
274 }
275}
276```
277
278Arguments passed to the CLI will always take precedence over the configuration in `package.json`.
279
280### Options
281
282- `files`: file & directory paths and glob patterns that select which files AVA will run tests from. Only files with a `.js` extension are used. Files with an underscore prefix are ignored. All `.js` files in selected directories are run
283- `source`: files that, when changed, cause tests to be re-run in watch mode. See the [watch mode recipe for details](https://github.com/avajs/ava/blob/master/docs/recipes/watch-mode.md#source-files-and-test-files)
284- `match`: not typically useful in the `package.json` configuration, but equivalent to [specifying `--match` on the CLI](#running-tests-with-matching-titles)
285- `failFast`: stop running further tests once a test fails
286- `failWithoutAssertions`: if `false`, does not fail a test if it doesn't run [assertions](#assertions)
287- `tap`: if `true`, enables the [TAP reporter](#tap-reporter)
288- `snapshotDir`: specifies a fixed location for storing snapshot files. Use this if your snapshots are ending up in the wrong location
289- `powerAssert`: if `false`, disables [power-assert](https://github.com/power-assert-js/power-assert) which otherwise helps provide more descriptive error messages
290- `require`: extra modules to require before tests are run. Modules are required in the [worker processes](#process-isolation)
291- `babel`: test file specific Babel options. See [ES2017 support](#es2017-support) for more details
292
293Note that providing files on the CLI overrides the `files` option. If you've configured a glob pattern, for instance `test/**/*.test.js`, you may want to repeat it when using the CLI: `ava 'test/integration/*.test.js'`.
294
295## Documentation
296
297Tests are run concurrently. You can specify synchronous and asynchronous tests. Tests are considered synchronous unless you return a promise or [observable](https://github.com/zenparsing/zen-observable).
298
299We *highly* recommend the use of [async functions](#async-function-support). They make asynchronous code concise and readable, and they implicitly return a promise so you don't have to.
300
301If you're unable to use promises or observables, you may enable "callback mode" by defining your test with `test.cb([title], fn)`. Tests declared this way **must** be manually ended with `t.end()`. This mode is mainly intended for testing callback-style APIs. However, we would strongly recommend [promisifying](https://github.com/sindresorhus/pify) callback-style APIs instead of using "callback mode", as this results in more correct and readable tests.
302
303You must define all tests synchronously. They can't be defined inside `setTimeout`, `setImmediate`, etc.
304
305AVA tries to run test files with their current working directory set to the directory that contains your `package.json` file.
306
307### Creating tests
308
309To create a test you call the `test` function you imported from AVA. Provide the optional title and implementation function. The function will be called when your test is run. It's passed an [execution object](#t) as its first argument.
310
311**Note:** In order for the [enhanced assertion messages](#enhanced-assertion-messages) to behave correctly, the first argument **must** be named `t`.
312
313```js
314import test from 'ava';
315
316test('my passing test', t => {
317 t.pass();
318});
319```
320
321#### Titles
322
323Titles are optional, meaning you can do:
324
325```js
326test(t => {
327 t.pass();
328});
329```
330
331It's recommended to provide test titles if you have more than one test.
332
333If you haven't provided a test title, but the implementation is a named function, that name will be used as the test title:
334
335```js
336test(function name(t) {
337 t.pass();
338});
339```
340
341### Assertion planning
342
343Assertion plans ensure tests only pass when a specific number of assertions have been executed. They'll help you catch cases where tests exit too early. They'll also cause tests to fail if too many assertions are executed, which can be useful if you have assertions inside callbacks or loops.
344
345If you do not specify an assertion plan, your test will still fail if no assertions are executed. Set the `failWithoutAssertions` option to `false` in AVA's [`package.json` configuration](#configuration) to disable this behavior.
346
347Note that, unlike [`tap`](https://www.npmjs.com/package/tap) and [`tape`](https://www.npmjs.com/package/tape), AVA does *not* automatically end a test when the planned assertion count is reached.
348
349These examples will result in a passed test:
350
351```js
352test(t => {
353 t.plan(1);
354
355 return Promise.resolve(3).then(n => {
356 t.is(n, 3);
357 });
358});
359
360test.cb(t => {
361 t.plan(1);
362
363 someAsyncFunction(() => {
364 t.pass();
365 t.end();
366 });
367});
368```
369
370These won't:
371
372```js
373test(t => {
374 t.plan(2);
375
376 for (let i = 0; i < 3; i++) {
377 t.true(i < 3);
378 }
379}); // Fails, 3 assertions are executed which is too many
380
381test(t => {
382 t.plan(1);
383
384 someAsyncFunction(() => {
385 t.pass();
386 });
387}); // Fails, the test ends synchronously before the assertion is executed
388```
389
390### Running tests serially
391
392Tests are run concurrently by default, however, sometimes you have to write tests that cannot run concurrently. In these rare cases you can use the `.serial` modifier. It will force those tests to run serially *before* the concurrent ones.
393
394```js
395test.serial(t => {
396 t.pass();
397});
398```
399
400Note that this only applies to tests within a particular test file. AVA will still run multiple tests files at the same time unless you pass the [`--serial` CLI flag](#cli).
401
402### Running specific tests
403
404During development it can be helpful to only run a few specific tests. This can be accomplished using the `.only` modifier:
405
406```js
407test('will not be run', t => {
408 t.fail();
409});
410
411test.only('will be run', t => {
412 t.pass();
413});
414```
415
416*Note:* The `.only` modifier applies to the test file it's defined in, so if you run multiple test files, tests in other files will still run. If you want to only run the `test.only` test, provide just that test file to AVA.
417
418### Running tests with matching titles
419
420The `--match` flag allows you to run just the tests that have a matching title. This is achieved with simple wildcard patterns. Patterns are case insensitive. See [`matcher`](https://github.com/sindresorhus/matcher) for more details.
421
422Match titles ending with `foo`:
423
424```console
425$ ava --match='*foo'
426```
427
428Match titles starting with `foo`:
429
430```console
431$ ava --match='foo*'
432```
433
434Match titles containing `foo`:
435
436```console
437$ ava --match='*foo*'
438```
439
440Match titles that are *exactly* `foo` (albeit case insensitively):
441
442```console
443$ ava --match='foo'
444```
445
446Match titles not containing `foo`:
447
448```console
449$ ava --match='!*foo*'
450```
451
452Match titles starting with `foo` and ending with `bar`:
453
454```console
455$ ava --match='foo*bar'
456```
457
458Match titles starting with `foo` or ending with `bar`:
459
460```console
461$ ava --match='foo*' --match='*bar'
462```
463
464Note that a match pattern takes precedence over the `.only` modifier. Only tests with an explicit title are matched. Tests without titles or whose title is derived from the implementation function will be skipped when `--match` is used.
465
466Here's what happens when you run AVA with a match pattern of `*oo*` and the following tests:
467
468```js
469test('foo will run', t => {
470 t.pass();
471});
472
473test('moo will also run', t => {
474 t.pass();
475});
476
477test.only('boo will run but not exclusively', t => {
478 t.pass();
479});
480
481// Won't run, no title
482test(function (t) {
483 t.fail();
484});
485
486// Won't run, no explicit title
487test(function foo(t) {
488 t.fail();
489});
490```
491
492### Skipping tests
493
494Sometimes failing tests can be hard to fix. You can tell AVA to skip these tests using the `.skip` modifier. They'll still be shown in the output (as having been skipped) but are never run.
495
496```js
497test.skip('will not be run', t => {
498 t.fail();
499});
500```
501
502You must specify the implementation function.
503
504### Test placeholders ("todo")
505
506You can use the `.todo` modifier when you're planning to write a test. Like skipped tests these placeholders are shown in the output. They only require a title; you cannot specify the implementation function.
507
508```js
509test.todo('will think about writing this later');
510```
511
512### Failing tests
513
514You can use the `.failing` modifier to document issues with your code that need to be fixed. Failing tests are run just like normal ones, but they are expected to fail, and will not break your build when they do. If a test marked as failing actually passes, it will be reported as an error and fail the build with a helpful message instructing you to remove the `.failing` modifier.
515
516This allows you to merge `.failing` tests before a fix is implemented without breaking CI. This is a great way to recognize good bug report PR's with a commit credit, even if the reporter is unable to actually fix the problem.
517
518```js
519// See: github.com/user/repo/issues/1234
520test.failing('demonstrate some bug', t => {
521 t.fail(); // Test will count as passed
522});
523```
524
525### Before & after hooks
526
527AVA lets you register hooks that are run before and after your tests. This allows you to run setup and/or teardown code.
528
529`test.before()` registers a hook to be run before the first test in your test file. Similarly `test.after()` registers a hook to be run after the last test. Use `test.after.always()` to register a hook that will **always** run once your tests and other hooks complete. `.always()` hooks run regardless of whether there were earlier failures or if all tests were skipped, so they are ideal for cleanup tasks. There are two exceptions to this however. If you use `--fail-fast` AVA will stop testing as soon as a failure occurs, and it won't run any hooks including the `.always()` hooks. Uncaught exceptions will crash your tests, possibly preventing `.always()` hooks from running.
530
531`test.beforeEach()` registers a hook to be run before each test in your test file. Similarly `test.afterEach()` a hook to be run after each test. Use `test.afterEach.always()` to register an after hook that is called even if other test hooks, or the test itself, fail. `.always()` hooks are ideal for cleanup tasks.
532
533If a test is skipped with the `.skip` modifier, the respective `.beforeEach()` and `.afterEach()` hooks are not run. Likewise, if all tests in a test file are skipped `.before()` and `.after()` hooks for the file are not run. Hooks modified with `.always()` will always run, even if all tests are skipped.
534
535**Note**: If the `--fail-fast` flag is specified, AVA will stop after the first test failure and the `.always` hook will **not** run.
536
537Like `test()` these methods take an optional title and a callback function. The title is shown if your hook fails to execute. The callback is called with an [execution object](#t).
538
539`before` hooks execute before `beforeEach` hooks. `afterEach` hooks execute before `after` hooks. Within their category the hooks execute in the order they were defined.
540
541```js
542test.before(t => {
543 // This runs before all tests
544});
545
546test.before(t => {
547 // This runs after the above, but before tests
548});
549
550test.after('cleanup', t => {
551 // This runs after all tests
552});
553
554test.after.always('guaranteed cleanup', t => {
555 // This will always run, regardless of earlier failures
556});
557
558test.beforeEach(t => {
559 // This runs before each test
560});
561
562test.afterEach(t => {
563 // This runs after each test
564});
565
566test.afterEach.always(t => {
567 // This runs after each test and other test hooks, even if they failed
568});
569
570test(t => {
571 // Regular test
572});
573```
574
575Hooks can be synchronous or asynchronous, just like tests. To make a hook asynchronous return a promise or observable, use an async function, or enable callback mode via `test.cb.before()`, `test.cb.beforeEach()` etc.
576
577```js
578test.before(async t => {
579 await promiseFn();
580});
581
582test.after(t => {
583 return new Promise(/* ... */);
584});
585
586test.cb.beforeEach(t => {
587 setTimeout(t.end);
588});
589
590test.afterEach.cb(t => {
591 setTimeout(t.end);
592});
593```
594
595Keep in mind that the `beforeEach` and `afterEach` hooks run just before and after a test is run, and that by default tests run concurrently. If you need to set up global state for each test (like spying on `console.log` [for example](https://github.com/avajs/ava/issues/560)), you'll need to make sure the tests are [run serially](#running-tests-serially).
596
597Remember that AVA runs each test file in its own process. You may not have to clean up global state in a `after`-hook since that's only called right before the process exits.
598
599#### Test context
600
601The `beforeEach` & `afterEach` hooks can share context with the test:
602
603```js
604test.beforeEach(t => {
605 t.context.data = generateUniqueData();
606});
607
608test(t => {
609 t.is(t.context.data + 'bar', 'foobar');
610});
611```
612
613The context is not shared between tests, allowing you to set up data in a way where it will not risk leaking to other, subsequent tests. By default `t.context` is an object but you can reassign it:
614
615```js
616test.beforeEach(t => {
617 t.context = 'unicorn';
618});
619
620test(t => {
621 t.is(t.context, 'unicorn');
622});
623```
624
625Context sharing is *not* available to `before` and `after` hooks.
626
627### Chaining test modifiers
628
629You can use the `.serial`, `.only` and `.skip` modifiers in any order, with `test`, `before`, `after`, `beforeEach` and `afterEach`. For example:
630
631```js
632test.before.skip(...);
633test.skip.after(...);
634test.serial.only(...);
635test.only.serial(...);
636```
637
638This means you can temporarily add `.skip` or `.only` at the end of a test or hook definition without having to make any other changes.
639
640### Test macros
641
642Additional arguments passed to the test declaration will be passed to the test implementation. This is useful for creating reusable test macros.
643
644```js
645function macro(t, input, expected) {
646 t.is(eval(input), expected);
647}
648
649test('2 + 2 = 4', macro, '2 + 2', 4);
650test('2 * 3 = 6', macro, '2 * 3', 6);
651```
652
653You can build the test title programmatically by attaching a `title` function to the macro:
654
655```js
656function macro(t, input, expected) {
657 t.is(eval(input), expected);
658}
659
660macro.title = (providedTitle, input, expected) => `${providedTitle} ${input} = ${expected}`.trim();
661
662test(macro, '2 + 2', 4);
663test(macro, '2 * 3', 6);
664test('providedTitle', macro, '3 * 3', 9);
665```
666
667The `providedTitle` argument defaults to an empty string if the user does not supply a string title. This allows for easy concatenation without having to worry about `null` / `undefined`. It is worth remembering that the empty string is considered a falsy value, so you can still use `if(providedTitle) {...}`.
668
669You can also pass arrays of macro functions:
670
671```js
672const safeEval = require('safe-eval');
673
674function evalMacro(t, input, expected) {
675 t.is(eval(input), expected);
676}
677
678function safeEvalMacro(t, input, expected) {
679 t.is(safeEval(input), expected);
680}
681
682test([evalMacro, safeEvalMacro], '2 + 2', 4);
683test([evalMacro, safeEvalMacro], '2 * 3', 6);
684```
685
686We encourage you to use macros instead of building your own test generators ([here is an example](https://github.com/avajs/ava-codemods/blob/47073b5b58aa6f3fb24f98757be5d3f56218d160/test/ok-to-truthy.js#L7-L9) of code that should be replaced with a macro). Macros are designed to perform static analysis of your code, which can lead to better performance, IDE integration, and linter rules.
687
688### Custom assertions
689
690You can use any assertion library instead of or in addition to the built-in one, provided it throws exceptions when the assertion fails.
691
692This won't give you as nice an experience as you'd get with the [built-in assertions](#assertions) though, and you won't be able to use the [assertion planning](#assertion-planning) ([see #25](https://github.com/avajs/ava/issues/25)).
693
694You'll have to configure AVA to not fail tests if no assertions are executed, because AVA can't tell if custom assertions pass. Set the `failWithoutAssertions` option to `false` in AVA's [`package.json` configuration](#configuration).
695
696```js
697import assert from 'assert';
698
699test(t => {
700 assert(true);
701});
702```
703
704### ES2017 support
705
706AVA comes with built-in support for ES2017 through [Babel 6](https://babeljs.io). Just write your tests in ES2017. No extra setup needed. You can use any Babel version in your project. We use our own bundled Babel with our [`@ava/stage-4`](https://github.com/avajs/babel-preset-stage-4) preset, as well as [custom transforms](https://github.com/avajs/babel-preset-transform-test-files) for test and helper files.
707
708The corresponding Babel config for AVA's setup is as follows:
709
710```json
711{
712 "presets": [
713 "@ava/stage-4",
714 "@ava/transform-test-files"
715 ]
716}
717```
718
719You can customize how AVA transpiles the test files through the `babel` option in AVA's [`package.json` configuration](#configuration). For example to override the presets you can use:
720
721```json
722{
723 "ava": {
724 "babel": {
725 "presets": [
726 "es2015",
727 "stage-0",
728 "react"
729 ]
730 }
731 }
732}
733```
734
735You can also use the special `"inherit"` keyword. This makes AVA defer to the Babel config in your [`.babelrc` or `package.json` file](https://babeljs.io/docs/usage/babelrc/). This way your test files will be transpiled using the same config as your source files without having to repeat it just for AVA:
736
737```json
738{
739 "babel": {
740 "presets": [
741 "es2015",
742 "stage-0",
743 "react"
744 ]
745 },
746 "ava": {
747 "babel": "inherit"
748 }
749}
750```
751
752See AVA's [`.babelrc` recipe](docs/recipes/babelrc.md) for further examples and a more detailed explanation of configuration options.
753
754Note that AVA will *always* apply [a few internal plugins](docs/recipes/babelrc.md#notes) regardless of configuration, but they should not impact the behavior of your code.
755
756### TypeScript support
757
758AVA includes typings for TypeScript. You have to set up transpilation yourself. When you set `module` to `commonjs` in your `tsconfig.json` file, TypeScript will automatically find the type definitions for AVA. You should set `target` to `es2015` to use promises and async functions.
759
760See AVA's [TypeScript recipe](docs/recipes/typescript.md) for a more detailed explanation.
761
762### Transpiling imported modules
763
764AVA currently only transpiles the tests you ask it to run, as well as test helpers (files starting with `_` or in `helpers` directory) inside the test directory. *It will not transpile modules you `import` from outside of the test.* This may be unexpected but there are workarounds.
765
766If you use Babel you can use its [require hook](https://babeljs.io/docs/usage/require/) to transpile imported modules on-the-fly. To add it, [configure it in your `package.json`](#configuration).
767
768You can also transpile your modules in a separate process and refer to the transpiled files rather than the sources from your tests. Example [here](docs/recipes/precompiling-with-webpack.md).
769
770### Promise support
771
772If you return a promise in the test you don't need to explicitly end the test as it will end when the promise resolves.
773
774```js
775test(t => {
776 return somePromise().then(result => {
777 t.is(result, 'unicorn');
778 });
779});
780```
781
782### Generator function support
783
784AVA comes with built-in support for [generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*).
785
786```js
787test(function * (t) {
788 const value = yield generatorFn();
789 t.true(value);
790});
791```
792
793### Async function support
794
795AVA comes with built-in support for [async functions](https://tc39.github.io/ecmascript-asyncawait/) *(async/await)*.
796
797```js
798test(async function (t) {
799 const value = await promiseFn();
800 t.true(value);
801});
802
803// Async arrow function
804test(async t => {
805 const value = await promiseFn();
806 t.true(value);
807});
808```
809
810### Observable support
811
812AVA comes with built-in support for [observables](https://github.com/zenparsing/es-observable). If you return an observable from a test, AVA will automatically consume it to completion before ending the test.
813
814*You do not need to use "callback mode" or call `t.end()`.*
815
816```js
817test(t => {
818 t.plan(3);
819 return Observable.of(1, 2, 3, 4, 5, 6)
820 .filter(n => {
821 // Only even numbers
822 return n % 2 === 0;
823 })
824 .map(() => t.pass());
825});
826```
827
828### Callback support
829
830AVA supports using `t.end` as the final callback when using node-style error-first callback APIs. AVA will consider any truthy value passed as the first argument to `t.end` to be an error. Note that `t.end` requires "callback mode", which can be enabled by using the `test.cb` chain.
831
832```js
833test.cb(t => {
834 // `t.end` automatically checks for error as first argument
835 fs.readFile('data.txt', t.end);
836});
837```
838
839### Global timeout
840
841A global timeout can be set via the `--timeout` option.
842Timeout in AVA behaves differently than in other test frameworks.
843AVA resets a timer after each test, forcing tests to quit if no new test results were received within the specified timeout.
844
845You can set timeouts in a human-readable way:
846
847```console
848$ ava --timeout=10s # 10 seconds
849$ ava --timeout=2m # 2 minutes
850$ ava --timeout=100 # 100 milliseconds
851```
852
853## API
854
855### `test([title], implementation)`
856### `test.serial([title], implementation)`
857### `test.cb([title], implementation)`
858### `test.only([title], implementation)`
859### `test.skip([title], implementation)`
860### `test.todo(title)`
861### `test.failing([title], implementation)`
862### `test.before([title], implementation)`
863### `test.after([title], implementation)`
864### `test.beforeEach([title], implementation)`
865### `test.afterEach([title], implementation)`
866
867#### `title`
868
869Type: `string`
870
871Test title.
872
873#### `implementation(t)`
874
875Type: `function`
876
877Should contain the actual test.
878
879##### `t`
880
881Type: `object`
882
883The execution object of a particular test. Each test implementation receives a different object. Contains the [assertions](#assertions) as well as `.plan(count)` and `.end()` methods. `t.context` can contain shared state from `beforeEach` hooks. `t.title` returns the test's title.
884
885###### `t.plan(count)`
886
887Plan how many assertion there are in the test. The test will fail if the actual assertion count doesn't match the number of planned assertions. See [assertion planning](#assertion-planning).
888
889###### `t.end()`
890
891End the test. Only works with `test.cb()`.
892
893###### `t.log(...values)`
894
895Log values contextually alongside the test result instead of immediately printing them to `stdout`. Behaves somewhat like `console.log`, but without support for placeholder tokens.
896
897## Assertions
898
899Assertions are mixed into the [execution object](#t) provided to each test implementation:
900
901```js
902test(t => {
903 t.truthy('unicorn'); // Assertion
904});
905```
906
907If multiple assertion failures are encountered within a single test, AVA will only display the *first* one.
908
909### `.pass([message])`
910
911Passing assertion.
912
913### `.fail([message])`
914
915Failing assertion.
916
917### `.truthy(value, [message])`
918
919Assert that `value` is truthy.
920
921### `.falsy(value, [message])`
922
923Assert that `value` is falsy.
924
925### `.true(value, [message])`
926
927Assert that `value` is `true`.
928
929### `.false(value, [message])`
930
931Assert that `value` is `false`.
932
933### `.is(value, expected, [message])`
934
935Assert that `value` is the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
936
937### `.not(value, expected, [message])`
938
939Assert that `value` is not the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
940
941### `.deepEqual(value, expected, [message])`
942
943Assert that `value` is deeply equal to `expected`. See [Concordance](https://github.com/concordancejs/concordance) for details. Works with [React elements and `react-test-renderer`](https://github.com/concordancejs/react).
944
945### `.notDeepEqual(value, expected, [message])`
946
947Assert that `value` is not deeply equal to `expected`. The inverse of `.deepEqual()`.
948
949### `.throws(function|promise, [error, [message]])`
950
951Assert that `function` throws an error, or `promise` rejects with an error.
952
953`error` can be an error constructor, error message, regex matched against the error message, or validation function.
954
955Returns the error thrown by `function` or a promise for the rejection reason of the specified `promise`.
956
957Example:
958
959```js
960const fn = () => {
961 throw new TypeError('🦄');
962};
963
964test('throws', t => {
965 const error = t.throws(() => {
966 fn();
967 }, TypeError);
968
969 t.is(error.message, '🦄');
970});
971```
972
973```js
974const promise = Promise.reject(new TypeError('🦄'));
975
976test('rejects', async t => {
977 const error = await t.throws(promise);
978 t.is(error.message, '🦄');
979});
980```
981
982When testing a promise you must wait for the assertion to complete:
983
984```js
985test('rejects', async t => {
986 await t.throws(promise);
987});
988```
989
990### `.notThrows(function|promise, [message])`
991
992Assert that `function` does not throw an error or that `promise` does not reject with an error.
993
994Like the `.throws()` assertion, when testing a promise you must wait for the assertion to complete:
995
996```js
997test('resolves', async t => {
998 await t.notThrows(promise);
999});
1000```
1001
1002### `.regex(contents, regex, [message])`
1003
1004Assert that `contents` matches `regex`.
1005
1006### `.notRegex(contents, regex, [message])`
1007
1008Assert that `contents` does not match `regex`.
1009
1010### `.ifError(error, [message])`
1011
1012Assert that `error` is falsy.
1013
1014### `.snapshot(expected, [message])`
1015### `.snapshot(expected, [options], [message])`
1016
1017Compares the `expected` value with a previously recorded snapshot. Snapshots are stored for each test, so ensure you give your tests unique titles. Alternatively pass an `options` object to select a specific snapshot, for instance `{id: 'my snapshot'}`.
1018
1019## Snapshot testing
1020
1021AVA supports snapshot testing, [as introduced by Jest](https://facebook.github.io/jest/docs/snapshot-testing.html), through its [Assertions](#assertions) interface. You can snapshot any value as well as React elements:
1022
1023```js
1024// Your component
1025const HelloWorld = () => <h1>Hello World...!</h1>;
1026
1027export default HelloWorld;
1028```
1029
1030```js
1031// Your test
1032import test from 'ava';
1033import render from 'react-test-renderer';
1034import HelloWorld from '.';
1035
1036test('HelloWorld component', t => {
1037 const tree = render.create(<HelloWorld/>).toJSON();
1038 t.snapshot(tree);
1039});
1040```
1041
1042[Try it out in this example project.](https://github.com/avajs/ava-snapshot-example)
1043
1044Snapshots are stored alongside your test files. If your tests are in a `test` or `tests` folder the snapshots will be stored in a `snapshots` folder. If your tests are in a `__tests__` folder then they they'll be stored in a `__snapshots__` folder.
1045
1046Say you have `~/project/test/main.js` which contains snapshot assertions. AVA will create two files:
1047
1048* `~/project/test/snapshots/main.js.snap`
1049* `~/project/test/snapshots/main.js.md`
1050
1051The first file contains the actual snapshot and is required for future comparisons. The second file contains your *snapshot report*. It's regenerated when you update your snapshots. If you commit it to source control you can diff it to see the changes to your snapshot.
1052
1053AVA will show why your snapshot assertion failed:
1054
1055<img src="media/snapshot-testing.png" width="1048">
1056
1057You can then check your code. If the change was intentional you can use the `--update-snapshots` (or `-u`) flag to update the snapshots:
1058
1059```console
1060$ ava --update-snapshots
1061```
1062
1063You can specify a fixed location for storing the snapshot files in AVA's [`package.json` configuration](#configuration):
1064
1065```json
1066{
1067 "ava": {
1068 "snapshotDir": "custom-directory"
1069 }
1070}
1071```
1072
1073The snapshot files will be saved in a directory structure that mirrors that of your test files.
1074
1075If you are running AVA against precompiled test files, AVA will try and use source maps to determine the location of the original files. Snapshots will be stored next to these files, following the same rules as if AVA had executed the original files directly. This is great if you're writing your tests in TypeScript (see our [TypeScript recipe](docs/recipes/typescript.md)).
1076
1077### Skipping assertions
1078
1079Any assertion can be skipped using the `skip` modifier. Skipped assertions are still counted, so there is no need to change your planned assertion count.
1080
1081```js
1082test(t => {
1083 t.plan(2);
1084 t.skip.is(foo(), 5); // No need to change your plan count when skipping
1085 t.is(1, 1);
1086});
1087```
1088
1089### Enhanced assertion messages
1090
1091AVA comes with [`power-assert`](https://github.com/power-assert-js/power-assert) built-in, giving you more descriptive assertion messages. It reads your test and tries to infer more information from the code.
1092
1093Let's take this example, using Node's standard [`assert` library](https://nodejs.org/api/assert.html):
1094
1095```js
1096const a = /foo/;
1097const b = 'bar';
1098const c = 'baz';
1099require('assert').ok(a.test(b) || b === c);
1100```
1101
1102If you paste that into a Node REPL it'll return:
1103
1104```
1105AssertionError: false == true
1106```
1107
1108In AVA however, this test:
1109
1110```js
1111test(t => {
1112 const a = /foo/;
1113 const b = 'bar';
1114 const c = 'baz';
1115 t.true(a.test(b) || b === c);
1116});
1117```
1118
1119Will output:
1120
1121```
1122t.true(a.test(b) || b === c)
1123 | | | |
1124 | "bar" "bar" "baz"
1125 false
1126```
1127
1128## Process isolation
1129
1130Each test file is run in a separate Node.js process. This allows you to change the global state or overriding a built-in in one test file, without affecting another. It's also great for performance on modern multi-core processors, allowing multiple test files to execute in parallel.
1131
1132AVA will set `process.env.NODE_ENV` to `test`, unless the `NODE_ENV` environment variable has been set. This is useful if the code you're testing has test defaults (for example when picking what database to connect to, or environment-specific Babel options). It may cause your code or its dependencies to behave differently though. Note that `'NODE_ENV' in process.env` will always be `true`.
1133
1134## Tips
1135
1136### Temp files
1137
1138Running tests concurrently comes with some challenges, doing file IO is one.
1139
1140Usually, serial tests create temp directories in the current test directory and clean them up at the end. This won't work when you run tests concurrently as tests will conflict with each other. The correct way to do it is to use a new temp directory for each test. The [`tempfile`](https://github.com/sindresorhus/tempfile) and [`temp-write`](https://github.com/sindresorhus/temp-write) modules can be helpful.
1141
1142### Code coverage
1143
1144You can't use [`istanbul`](https://github.com/gotwarlost/istanbul) for code coverage as AVA [spawns the test files](#process-isolation). You can use [`nyc`](https://github.com/bcoe/nyc) instead, which is basically `istanbul` with support for subprocesses.
1145
1146As of version `5.0.0` it uses source maps to report coverage for your actual code, regardless of transpilation. Make sure that the code you're testing includes an inline source map or references a source map file. If you use `babel-register` you can set the `sourceMaps` option in your Babel config to `inline`.
1147
1148### Common pitfalls
1149
1150We have a growing list of [common pitfalls](docs/common-pitfalls.md) you may experience while using AVA. If you encounter any issues you think are common, comment in [this issue](https://github.com/avajs/ava/issues/404).
1151
1152## FAQ
1153
1154### Why not `mocha`, `tape`, `tap`?
1155
1156Mocha requires you to use implicit globals like `describe` and `it` with the default interface (which most people use). It's not very opinionated and executes tests serially without process isolation, making it slow.
1157
1158Tape and tap are pretty good. AVA is highly inspired by their syntax. They too execute tests serially. Their default [TAP](https://testanything.org) output isn't very user-friendly though so you always end up using an external tap reporter.
1159
1160In contrast AVA is highly opinionated and runs tests concurrently, with a separate process for each test file. Its default reporter is easy on the eyes and yet AVA still supports TAP output through a CLI flag.
1161
1162### How is the name written and pronounced?
1163
1164AVA, not Ava or ava. Pronounced [`/ˈeɪvə/` ay-və](media/pronunciation.m4a?raw=true).
1165
1166### What is the header background?
1167
1168It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy).
1169
1170### What is the difference between concurrency and parallelism?
1171
1172[Concurrency is not parallelism. It enables parallelism.](https://stackoverflow.com/q/1050222)
1173
1174## Recipes
1175
1176- [Code coverage](docs/recipes/code-coverage.md)
1177- [Watch mode](docs/recipes/watch-mode.md)
1178- [Endpoint testing](docs/recipes/endpoint-testing.md)
1179- [When to use `t.plan()`](docs/recipes/when-to-use-plan.md)
1180- [Browser testing](docs/recipes/browser-testing.md)
1181- [TypeScript](docs/recipes/typescript.md)
1182- [Configuring Babel](docs/recipes/babelrc.md)
1183- [Testing React components](docs/recipes/react.md)
1184- [Testing Vue.js components](docs/recipes/vue.md)
1185- [JSPM and SystemJS](docs/recipes/jspm-systemjs.md)
1186- [Debugging tests with Chrome DevTools](docs/recipes/debugging-with-chrome-devtools.md)
1187- [Debugging tests with WebStorm](docs/recipes/debugging-with-webstorm.md)
1188- [Precompiling source files with webpack](docs/recipes/precompiling-with-webpack.md)
1189- [Isolated MongoDB integration tests](docs/recipes/isolated-mongodb-integration-tests.md)
1190
1191## Support
1192
1193- [Stack Overflow](https://stackoverflow.com/questions/tagged/ava)
1194- [Gitter chat](https://gitter.im/avajs/ava)
1195- [Twitter](https://twitter.com/ava__js)
1196
1197## Related
1198
1199- [eslint-plugin-ava](https://github.com/avajs/eslint-plugin-ava) - Lint rules for AVA tests
1200- [sublime-ava](https://github.com/avajs/sublime-ava) - Snippets for AVA tests
1201- [atom-ava](https://github.com/avajs/atom-ava) - Snippets for AVA tests
1202- [vscode-ava](https://github.com/samverschueren/vscode-ava) - Snippets for AVA tests
1203- [gulp-ava](https://github.com/avajs/gulp-ava) - Run tests with gulp
1204- [grunt-ava](https://github.com/avajs/grunt-ava) - Run tests with grunt
1205- [More…](https://github.com/avajs/awesome-ava#packages)
1206
1207## Links
1208
1209- [Buy AVA stickers](https://www.stickermule.com/user/1070705604/stickers)
1210- [Awesome list](https://github.com/avajs/awesome-ava)
1211- [AVA Casts](http://avacasts.com)
1212- [More…](https://github.com/avajs/awesome-ava)
1213
1214## Team
1215
1216[![Sindre Sorhus](https://github.com/sindresorhus.png?size=100)](https://github.com/sindresorhus) | [![Vadim Demedes](https://github.com/vadimdemedes.png?size=100)](https://github.com/vadimdemedes) | [![James Talmage](https://github.com/jamestalmage.png?size=100)](https://github.com/jamestalmage) | [![Mark Wubben](https://github.com/novemberborn.png?size=100)](https://github.com/novemberborn) | [![Juan Soto](https://github.com/sotojuan.png?size=100)](https://github.com/sotojuan) | [![Jeroen Engels](https://github.com/jfmengels.png?size=100)](https://github.com/jfmengels)
1217---|---|---|---|---|---
1218[Sindre Sorhus](http://sindresorhus.com) | [Vadim Demedes](https://github.com/vadimdemedes) | [James Talmage](https://github.com/jamestalmage) | [Mark Wubben](https://novemberborn.net) | [Juan Soto](http://juansoto.me) | [Jeroen Engels](https://github.com/jfmengels)
1219
1220### Former
1221
1222- [Kevin Mårtensson](https://github.com/kevva)
1223
1224
1225<div align="center">
1226 <br>
1227 <br>
1228 <br>
1229 <a href="https://ava.li">
1230 <img src="https://cdn.rawgit.com/avajs/ava/fe1cea1ca3d2c8518c0cc39ec8be592beab90558/media/logo.svg" width="200" alt="AVA">
1231 </a>
1232 <br>
1233 <br>
1234</div>