1 | # nyc
|
2 |
|
3 | [![Build Status](https://travis-ci.org/istanbuljs/nyc.svg?branch=master)](https://travis-ci.org/istanbuljs/nyc)
|
4 | [![Coverage Status](https://coveralls.io/repos/bcoe/nyc/badge.svg?branch=)](https://coveralls.io/r/bcoe/nyc?branch=master)
|
5 | [![NPM version](https://img.shields.io/npm/v/nyc.svg)](https://www.npmjs.com/package/nyc)
|
6 | [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
|
7 | [![community slack](http://devtoolscommunity.herokuapp.com/badge.svg)](http://devtoolscommunity.herokuapp.com)
|
8 |
|
9 | _Having problems? want to contribute? join our [community slack](http://devtoolscommunity.herokuapp.com)_.
|
10 |
|
11 | Istanbul's state of the art command line interface, with support for:
|
12 |
|
13 | * applications that spawn subprocesses.
|
14 | * ES2015 transforms, via [`babel-plugin-istanbul`], or source-maps.
|
15 |
|
16 | ## Instrumenting your code
|
17 |
|
18 | You can install nyc as a development dependency and add it to the test stanza
|
19 | in your package.json.
|
20 |
|
21 | ```shell
|
22 | npm i nyc --save-dev
|
23 | ```
|
24 |
|
25 | ```json
|
26 | {
|
27 | "scripts": {
|
28 | "test": "nyc mocha"
|
29 | }
|
30 | }
|
31 | ```
|
32 |
|
33 | Alternatively, you can install nyc globally and use it to execute `npm test`:
|
34 |
|
35 | ```shell
|
36 | npm i nyc -g
|
37 | ```
|
38 |
|
39 | ```shell
|
40 | nyc npm test
|
41 | ```
|
42 |
|
43 | nyc accepts a wide variety of configuration arguments, run `nyc --help` for
|
44 | thorough documentation.
|
45 |
|
46 | Configuration arguments should be provided prior to the program that nyc
|
47 | is executing. As an example, the following command executes `npm test`,
|
48 | and indicates to nyc that it should output both an `lcov`
|
49 | and a `text-lcov` coverage report.
|
50 |
|
51 | ```shell
|
52 | nyc --reporter=lcov --reporter=text-lcov npm test
|
53 | ```
|
54 |
|
55 | ### Accurate stack traces using source-maps
|
56 |
|
57 | When `produce-source-map` is set to true, then the instrumented source files will
|
58 | include inline source maps for the instrumenter transform. When combined with
|
59 | [source-map-support](https://github.com/evanw/node-source-map-support),
|
60 | stack traces for instrumented code will reflect their original lines.
|
61 |
|
62 | ### Support for custom require hooks (babel, typescript, etc.)
|
63 |
|
64 | nyc supports custom require hooks like [`@babel/register`]. nyc can load
|
65 | the hooks for you, [using the `--require` flag](#require-additional-modules).
|
66 |
|
67 | Source maps are used to map coverage information back to the appropriate lines
|
68 | of the pre-transpiled code. You'll have to configure your custom require hook
|
69 | to inline the source-map in the transpiled code. For Babel that means setting
|
70 | the `sourceMaps` option to `inline`.
|
71 |
|
72 | ### Source-Map support for pre-instrumented codebases
|
73 |
|
74 | If you opt to pre-instrument your source-code (rather than using a just-in-time
|
75 | transpiler like [`@babel/register`]) nyc supports both inline source-maps and
|
76 | `.map` files.
|
77 |
|
78 | _Important: If you are using nyc with a project that pre-instruments its code,
|
79 | run nyc with the configuration option `--exclude-after-remap` set to `false`.
|
80 | Otherwise nyc's reports will exclude any files that source-maps remap to folders
|
81 | covered under exclude rules._
|
82 |
|
83 | ## Use with `babel-plugin-istanbul` for Babel Support
|
84 |
|
85 | We recommend using [`babel-plugin-istanbul`] if your project uses the babel tool chain:
|
86 |
|
87 | 1. enable the `babel-plugin-istanbul` plugin:
|
88 |
|
89 | ```json
|
90 | {
|
91 | "babel": {
|
92 | "presets": ["@babel/preset-env"],
|
93 | "env": {
|
94 | "test": {
|
95 | "plugins": ["istanbul"]
|
96 | }
|
97 | }
|
98 | }
|
99 | }
|
100 | ```
|
101 |
|
102 | Note: With this configuration, the Istanbul instrumentation will only be active when `NODE_ENV` or `BABEL_ENV` is `test` unless the environment is a valid entry in `"env"` within the `.babelrc` file.
|
103 |
|
104 | We recommend using the [`cross-env`](https://npmjs.com/package/cross-env) package to set these environment variables
|
105 | in your `package.json` scripts in a way that works cross-platform.
|
106 |
|
107 | 2. disable nyc's instrumentation and source-maps, e.g. in `package.json`:
|
108 |
|
109 | ```json
|
110 | {
|
111 | "nyc": {
|
112 | "require": [
|
113 | "@babel/register"
|
114 | ],
|
115 | "sourceMap": false,
|
116 | "instrument": false
|
117 | },
|
118 | "scripts": {
|
119 | "test": "cross-env NODE_ENV=test nyc mocha"
|
120 | }
|
121 | }
|
122 | ```
|
123 |
|
124 | That's all there is to it, better ES2015+ syntax highlighting awaits:
|
125 |
|
126 | <img width="500" src="screen2.png">
|
127 |
|
128 | ## Support for alternate file extensions (.jsx, .mjs)
|
129 |
|
130 | Supporting file extensions can be configured through either the configuration arguments or with the `nyc` config section in `package.json`.
|
131 |
|
132 | ```shell
|
133 | nyc --extension .jsx --extension .mjs npm test
|
134 | ```
|
135 |
|
136 | ```json
|
137 | {
|
138 | "nyc": {
|
139 | "extension": [
|
140 | ".jsx",
|
141 | ".mjs"
|
142 | ]
|
143 | }
|
144 | }
|
145 | ```
|
146 |
|
147 | ## Checking coverage
|
148 |
|
149 | nyc can fail tests if coverage falls below a threshold.
|
150 | After running your tests with nyc, simply run:
|
151 |
|
152 | ```shell
|
153 | nyc check-coverage --lines 95 --functions 95 --branches 95
|
154 | ```
|
155 |
|
156 | nyc also accepts a `--check-coverage` shorthand, which can be used to
|
157 | both run tests and check that coverage falls within the threshold provided:
|
158 |
|
159 | ```shell
|
160 | nyc --check-coverage --lines 100 npm test
|
161 | ```
|
162 |
|
163 | The above check fails if coverage falls below 100%.
|
164 |
|
165 | To check thresholds on a per-file basis run:
|
166 |
|
167 | ```shell
|
168 | nyc check-coverage --lines 95 --per-file
|
169 | ```
|
170 |
|
171 | ## Running reports
|
172 |
|
173 | Once you've run your tests with nyc, simply run:
|
174 |
|
175 | ```bash
|
176 | nyc report
|
177 | ```
|
178 |
|
179 | To view your coverage report:
|
180 |
|
181 | <img width="500" src="screen.png">
|
182 |
|
183 | You can use [any reporters that are supported by `istanbul`](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib): `clover`, `cobertura`, `html`, `json-summary`, `json`, `lcov`, `lcovonly`, `none`, `teamcity`, `text-lcov`, `text-summary`, `text`.
|
184 |
|
185 | ```bash
|
186 | nyc report --reporter=lcov
|
187 | ```
|
188 |
|
189 | You can find examples of the output for various reporters [here](https://istanbul.js.org/docs/advanced/alternative-reporters).
|
190 |
|
191 | You also have the choice of using a [custom reporter](https://github.com/pedrocarrico/istanbul-reporter-aws-cloudwatch-metrics).
|
192 | Install custom reporters as a development dependency and you can use the `--reporter` flag to load and view them:
|
193 |
|
194 | ```bash
|
195 | nyc report --reporter=<custom-reporter-name>
|
196 | ```
|
197 |
|
198 | ## Producing instrumented source
|
199 |
|
200 | The `nyc instrument` command can produce a set of instrumented source files.
|
201 | These files are suitable for client side deployment in end to end testing.
|
202 | You can create an instrumented version of your source code by running:
|
203 |
|
204 | ```bash
|
205 | nyc instrument <input> [output]
|
206 | ```
|
207 |
|
208 | `<input>` can be any file or directory within the project root directory.
|
209 | The `[output]` directory is optional and can be located anywhere, if it is not set the instrumented code will be sent to `stdout`.
|
210 | For example, `nyc instrument . ./output` will produce instrumented versions of any source files it finds in `.` and store them in `./output`.
|
211 |
|
212 | Any existing output can be removed by specifying the `--delete` option.
|
213 | Run `nyc instrument --help` to display a full list of available command options.
|
214 |
|
215 | **Note:** `nyc instrument` will not copy the contents of a `.git` folder to the output directory.
|
216 |
|
217 | ## Setting the project root directory
|
218 |
|
219 | nyc runs a lot of file system operations relative to the project root directory.
|
220 | During startup nyc will look for the *default* project root directory.
|
221 | The *default* project root directory is the first directory found that contains a `package.json` file when searching from the current working directory up.
|
222 | If nyc fails to find a directory containing a `package.json` file, it will use the current working directory as the *default* project root directory.
|
223 | You can change the project root directory with the `--cwd` option.
|
224 |
|
225 | nyc uses the project root directory when:
|
226 | * looking for source files to instrument
|
227 | * creating globs for include and exclude rules during file selection
|
228 | * loading custom require hooks from the `require` array
|
229 |
|
230 | nyc may create artefact directories within the project root, such as:
|
231 | * the report directory, `<project-root>/coverage`
|
232 | * the cache directory, `<project-root>/node_modules/.cache/nyc`
|
233 | * the temp directory, `<project-root>/.nyc_output`
|
234 |
|
235 | ## Selecting files for coverage
|
236 |
|
237 | By default, nyc only collects coverage for source files that are visited during a test.
|
238 | It does this by watching for files that are `require()`'d during the test.
|
239 | When a file is `require()`'d, nyc creates and returns an instrumented version of the source, rather than the original.
|
240 | Only source files that are visited during a test will appear in the coverage report and contribute to coverage statistics.
|
241 |
|
242 | nyc will instrument all files if the `--all` flag is set or if running `nyc instrument`.
|
243 | In this case all files will appear in the coverage report and contribute to coverage statistics.
|
244 |
|
245 | nyc will only collect coverage for files that are located under `cwd`, and then only `*.js` files or files with extensions listed in the `extension` array.
|
246 |
|
247 | You can reduce the set of instrumented files by adding `include` and `exclude` filter arrays to your config.
|
248 | These allow you to shape the set of instrumented files by specifying glob patterns that can filter files from the default instrumented set.
|
249 | The `exclude` array may also use exclude negated glob patterns, these are specified with a `!` prefix, and can restore sub-paths of excluded paths.
|
250 |
|
251 | Globs are matched using [minimatch](https://www.npmjs.com/package/minimatch).
|
252 |
|
253 | We use the following process to remove files from consideration:
|
254 | 1. Limit the set of instrumented files to those files in paths listed in the `include` array.
|
255 | 2. Remove any files that are found in the `exclude` array.
|
256 | 3. Restore any exclude negated files that have been excluded in step 2.
|
257 |
|
258 | ### Using include and exclude arrays
|
259 |
|
260 | If there are paths specified in the `include` array, then the set of instrumented files will be limited to eligible files found in those paths.
|
261 | If the `include` array is left undefined all eligible files will be included, equivalent to setting `include: ['**']`.
|
262 | Multiple `include` globs can be specified on the command line, each must follow a `--include`, `-n` switch.
|
263 |
|
264 | If there are paths specified in the `exclude` array, then the set of instrumented files will not feature eligible files found in those paths.
|
265 | You can also specify negated paths in the `exclude` array, by prefixing them with a `!`.
|
266 | Negated paths can restore paths that have been already been excluded in the `exclude` array.
|
267 | Multiple `exclude` globs can be specified on the command line, each must follow a `--exclude`, `-x` switch.
|
268 |
|
269 | The `exclude` option has the following defaults settings:
|
270 | ```js
|
271 | [
|
272 | 'coverage/**',
|
273 | 'packages/*/test/**',
|
274 | 'test/**',
|
275 | 'test{,-*}.js',
|
276 | '**/*{.,-}test.js',
|
277 | '**/__tests__/**',
|
278 | '**/node_modules/**',
|
279 | '**/babel.config.js'
|
280 | ]
|
281 | ```
|
282 | These settings exclude `test` and `__tests__` directories as well as `test.js`, `*.test.js`, and `test-*.js` files.
|
283 | Specifying your own exclude property completely replaces these defaults.
|
284 |
|
285 | For example, the following config will collect coverage for every file in the `src` directory regardless of whether it is `require()`'d in a test.
|
286 | It will also exclude any files with the extension `.spec.js`.
|
287 |
|
288 | ```json
|
289 | {
|
290 | "nyc": {
|
291 | "all": true,
|
292 | "include": [
|
293 | "src/**/*.js"
|
294 | ],
|
295 | "exclude": [
|
296 | "**/*.spec.js"
|
297 | ]
|
298 | }
|
299 | }
|
300 | ```
|
301 |
|
302 | **Note:** Be wary of automatic OS glob expansion when specifying include/exclude globs with the CLI.
|
303 | To prevent this, wrap each glob in single quotes.
|
304 |
|
305 | ### Including files within `node_modules`
|
306 |
|
307 | We always add `**/node_modules/**` to the exclude list, even if not specified in the config.
|
308 | You can override this by setting `--exclude-node-modules=false`.
|
309 |
|
310 | For example, in the following config, `"excludeNodeModules: false"` will prevent `node_modules` from being added to the exclude rules.
|
311 | The set of include rules then restrict nyc to only consider instrumenting files found under the `lib/` and `node_modules/@my-org/` directories.
|
312 | The exclude rules then prevent nyc instrumenting anything in a `test` folder and the file `node_modules/@my-org/something/unwanted.js`.
|
313 |
|
314 | ```json
|
315 | {
|
316 | "nyc": {
|
317 | "all": true,
|
318 | "include": [
|
319 | "lib/**",
|
320 | "node_modules/@my-org/**"
|
321 | ],
|
322 | "exclude": [
|
323 | "node_modules/@my-org/something/unwanted.js",
|
324 | "**/test/**"
|
325 | ],
|
326 | "excludeNodeModules": false
|
327 | }
|
328 | }
|
329 | ```
|
330 |
|
331 | ## Require additional modules
|
332 |
|
333 | The `--require` flag can be provided to `nyc` to indicate that additional
|
334 | modules should be required in the subprocess collecting coverage:
|
335 |
|
336 | `nyc --require @babel/register --require @babel/polyfill mocha`
|
337 |
|
338 | ## Caching
|
339 |
|
340 | `nyc`'s default behavior is to cache instrumented files to disk to prevent instrumenting source files multiple times, and speed `nyc` execution times. You can disable this behavior by running `nyc` with the `--cache false` flag. You can also change the default cache directory from `./node_modules/.cache/nyc` by setting the `--cache-dir` flag.
|
341 |
|
342 | ## Configuring `nyc`
|
343 |
|
344 | Any configuration options that can be set via the command line can also be specified in the `nyc` stanza of your package.json, or within a `.nycrc`, `.nycrc.json`, or `nyc.config.js` file:
|
345 |
|
346 | **package.json:**
|
347 |
|
348 | ```json
|
349 | {
|
350 | "description": "These are just examples for demonstration, nothing prescriptive",
|
351 | "nyc": {
|
352 | "check-coverage": true,
|
353 | "per-file": true,
|
354 | "lines": 99,
|
355 | "statements": 99,
|
356 | "functions": 99,
|
357 | "branches": 99,
|
358 | "include": [
|
359 | "src/**/*.js"
|
360 | ],
|
361 | "exclude": [
|
362 | "src/**/*.spec.js"
|
363 | ],
|
364 | "ignore-class-method": "methodToIgnore",
|
365 | "reporter": [
|
366 | "lcov",
|
367 | "text-summary"
|
368 | ],
|
369 | "require": [
|
370 | "./test/helpers/some-helper.js"
|
371 | ],
|
372 | "extension": [
|
373 | ".jsx"
|
374 | ],
|
375 | "cache": true,
|
376 | "all": true,
|
377 | "temp-dir": "./alternative-tmp",
|
378 | "report-dir": "./alternative"
|
379 | }
|
380 | }
|
381 | ```
|
382 |
|
383 | Configuration can also be provided by `nyc.config.js` if programmed logic is required:
|
384 | ```js
|
385 | 'use strict';
|
386 | const {defaultExclude} = require('test-exclude');
|
387 | const isWindows = require('is-windows');
|
388 |
|
389 | let platformExclude = [
|
390 | isWindows() ? 'lib/posix.js' : 'lib/win32.js'
|
391 | ];
|
392 |
|
393 | module.exports = {
|
394 | exclude: platformExclude.concat(defaultExclude)
|
395 | };
|
396 | ```
|
397 |
|
398 | ### Publish, and reuse, your nyc configuration
|
399 |
|
400 | nyc allows you to inherit other configurations using the key `extends`. As an example,
|
401 | an alternative way to configure nyc for `babel-plugin-istanbul` would be to use the
|
402 | [@istanbuljs/nyc-config-babel preset](https://www.npmjs.com/package/@istanbuljs/nyc-config-babel):
|
403 |
|
404 | ```json
|
405 | {
|
406 | "nyc": {
|
407 | "extends": "@istanbuljs/nyc-config-babel"
|
408 | }
|
409 | }
|
410 | ```
|
411 |
|
412 | To publish and resuse your own `nyc` configuration, simply create an npm module that
|
413 | exports an `index.json` with your `nyc` config.
|
414 |
|
415 | ## High and low watermarks
|
416 |
|
417 | Several of the coverage reporters supported by nyc display special information
|
418 | for high and low watermarks:
|
419 |
|
420 | * high-watermarks represent healthy test coverage (in many reports
|
421 | this is represented with green highlighting).
|
422 | * low-watermarks represent sub-optimal coverage levels (in many reports
|
423 | this is represented with red highlighting).
|
424 |
|
425 | You can specify custom high and low watermarks in nyc's configuration:
|
426 |
|
427 | ```json
|
428 | {
|
429 | "nyc": {
|
430 | "watermarks": {
|
431 | "lines": [80, 95],
|
432 | "functions": [80, 95],
|
433 | "branches": [80, 95],
|
434 | "statements": [80, 95]
|
435 | }
|
436 | }
|
437 | }
|
438 | ```
|
439 |
|
440 | ## Parsing Hints (Ignoring Lines)
|
441 |
|
442 | There may be some sections of your codebase that you wish to purposefully
|
443 | exclude from coverage tracking, to do so you can use the following parsing
|
444 | hints:
|
445 |
|
446 | * `/* istanbul ignore if */`: ignore the next if statement.
|
447 | * `/* istanbul ignore else */`: ignore the else portion of an if statement.
|
448 | * `/* istanbul ignore next */`: ignore the next _thing_ in the source-code (
|
449 | functions, if statements, classes, you name it).
|
450 | * `/* istanbul ignore file */`: ignore an entire source-file (this should be
|
451 | placed at the top of the file).
|
452 |
|
453 | ## Ignoring Methods
|
454 |
|
455 | There may be some methods that you want to universally ignore out of your classes
|
456 | rather than having to ignore every instance of that method:
|
457 |
|
458 | ```json
|
459 | {
|
460 | "nyc": {
|
461 | "ignore-class-method": "render"
|
462 | }
|
463 | }
|
464 | ```
|
465 |
|
466 | ## [Integrating with coveralls](./docs/setup-coveralls.md)
|
467 |
|
468 | ## [Integrating with codecov](./docs/setup-codecov.md)
|
469 |
|
470 | ## Integrating with TAP formatters
|
471 |
|
472 | Many testing frameworks (Mocha, Tape, Tap, etc.) can produce [TAP](https://en.wikipedia.org/wiki/Test_Anything_Protocol) output. [tap-nyc](https://github.com/MegaArman/tap-nyc) is a TAP formatter designed to look nice with nyc.
|
473 |
|
474 | ## More tutorials
|
475 |
|
476 | You can find more tutorials at http://istanbul.js.org/docs/tutorials
|
477 |
|
478 | ## Other advanced features
|
479 |
|
480 | Take a look at http://istanbul.js.org/docs/advanced/ and please feel free to [contribute documentation](https://github.com/istanbuljs/istanbuljs.github.io/tree/development/content).
|
481 |
|
482 | [`@babel/register`]: https://www.npmjs.com/package/@babel/register
|
483 | [`babel-plugin-istanbul`]: https://github.com/istanbuljs/babel-plugin-istanbul
|