Saves the code coverage collected during Cypress tests
npm install -D @cypress/code-coverageNote: this plugin assumes cypress is a peer dependency already installed in your project.
Add to your cypress/support/index.js file
import '@cypress/code-coverage/support'Register tasks in your cypress/plugins/index.js file
module.exports = (on, config) => { require('@cypress/code-coverage/task')(on, config) // IMPORTANT to return the config object // with the any changed environment variables return config }This plugin DOES NOT instrument your code. You have to instrument it yourself using Istanbul.js tool. Luckily it is not difficult. For example, if you are already using Babel to transpile you can add babel-plugin-istanbul to your .babelrc and instrument on the fly.
{ "plugins": ["istanbul"] } Please see the Examples section down below, you can probably find a linked project matching your situation to see how to instrument your application's source code before running end-to-end tests to get the code coverage.
If your application has been instrumented correctly, then you should see additional counters and instructions in the application's JavaScript resources, like the image down below shows.
You should see the window.__coverage__ object in the "Application under test iframe"
If you have instrumented your application's code and see the window.__coverage__ object, then this plugin will save the coverage into .nyc_output folder and will generate reports after the tests finish (even in the interactive mode). Find the LCOV and HTML report in the coverage/lcov-report folder.
That should be it!
The coverage folder has results in several formats, and the coverage raw data is stored in .nyc_output folder. You can see the coverage numbers yourself. This plugin has nyc as a dependency, so it should be available right away. Here are common examples:
# see just the coverage summary $ npx nyc report --reporter=text-summary # see just the coverage file by file $ npx nyc report --reporter=text # save the HTML report again $ npx nyc report --reporter=lcovIt is useful to enforce minimum coverage numbers. For example:
$ npx nyc report --check-coverage --lines 80 ----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 100 | 100 | 100 | 100 | main.js | 100 | 100 | 100 | 100 | ----------|---------|----------|---------|---------|------------------- $ npx nyc report --check-coverage --lines 101 ----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 100 | 100 | 100 | 100 | main.js | 100 | 100 | 100 | 100 | ----------|---------|----------|---------|---------|------------------- ERROR: Coverage for lines (100%) does not meet global threshold (101%)If you test your application code directly from specs you might want to instrument them and combine unit test code coverage with any end-to-end code coverage (from iframe). You can easily instrument spec files using babel-plugin-istanbul for example.
Install the plugin
npm i -D babel-plugin-istanbul Set your .babelrc file
{ "plugins": ["istanbul"] } Put the following in cypress/plugins/index.js file to use .babelrc file
module.exports = (on, config) => { require('@cypress/code-coverage/task')(on, config) on('file:preprocessor', require('@cypress/code-coverage/use-babelrc')) return config }Now the code coverage from spec files will be combined with end-to-end coverage.
If you cannot use .babelrc for some reason (maybe it is used by other tools?), try using the Browserify transformer included with this module in use-browserify-istanbul file.
module.exports = (on, config) => { require('@cypress/code-coverage/task')(on, config) on( 'file:preprocessor', require('@cypress/code-coverage/use-browserify-istanbul') ) return config }Example in examples/backend folder.
You can also instrument your server-side code and produce combined coverage report that covers both the backend and frontend code
- Run the server code with instrumentation. The simplest way is to use nyc. If normally you run
node src/serverthen to run instrumented version you can donyc --silent node src/server. - Add an endpoint that returns collected coverage. If you are using Express, you can simply do
const express = require('express') const app = express() require('@cypress/code-coverage/middleware/express')(app)Tip: you can register the endpoint only if there is global code coverage object, and you can exclude the middleware code from the coverage numbers
// https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md /* istanbul ignore next */ if (global.__coverage__) { require('@cypress/code-coverage/middleware/express')(app) }If you use Hapi server, define the endpoint yourself and return the object
if (global.__coverage__) { require('@cypress/code-coverage/middleware/hapi')(server) }For any other server, define the endpoint yourself and return the coverage object:
if (global.__coverage__) { // add method "GET /__coverage__" and response with JSON onRequest = response => response.sendJSON({ coverage: global.__coverage__ }) }- Save the API coverage endpoint in
cypress.jsonfile to let the plugin know where to call to receive the code coverage data from the server. Place it inenv.codeCoverageobject:
{ "env": { "codeCoverage": { "url": "http://localhost:3000/__coverage__" } } }That should be enough - the code coverage from the server will be requested at the end of the test run and merged with the client-side code coverage, producing a combined report.
You can specify custom report folder by adding nyc object to the package.json file. For example to save reports to cypress-coverage folder, use:
{ "nyc": { "report-dir": "cypress-coverage" } }You can specify custom coverage reporter(s) to use. For example to output text summary and save JSON report in cypress-coverage folder set in your package.json folder:
{ "nyc": { "report-dir": "cypress-coverage", "reporter": ["text", "json"] } }Tip: find list of reporters here
Sometimes NYC tool might be installed in a different folder not in the current or parent folder, or you might want to customize the report command. In that case, put the custom command into package.json in the current folder and this plugin will automatically use it.
{ "scripts": { "coverage:report": "call NYC report ..." } }TypeScript source files should be automatically included in the report, if they are instrumented.
See examples/ts-example, bahmutov/cra-ts-code-coverage-example or bahmutov/cypress-angular-coverage-example.
You can exclude parts of the code or entire files from the code coverage report. See Istanbul guide. Common cases:
When running code only during Cypress tests, the "else" branch will never be hit. Thus we should exclude it from the branch coverage computation:
// expose "store" reference during tests /* istanbul ignore else */ if (window.Cypress) { window.store = store }Often needed to skip a statement
/* istanbul ignore next */ if (global.__coverage__) { require('@cypress/code-coverage/middleware/express')(app) }Or a particular switch case
switch (foo) { case 1 /* some code */: break /* istanbul ignore next */ case 2: // really difficult to hit from tests someCode() }See nyc configuration and include and exclude options. You can include and exclude files using minimatch patterns in .nycrc file or using "nyc" object inside your package.json file.
For example, if you want to only include files in the app folder, but exclude app/util.js file, you can set in your package.json
{ "nyc": { "include": ["app/**/*.js"], "exclude": ["app/util.js"] } }You can skip the client-side code coverage hooks by setting the environment variable coverage to false.
cypress run --env coverage=falseSee Cypress environment variables and support.js. You can try running without code coverage in this project yourself
# run with code coverage npm run dev # disable code coverage npm run dev:no:coverage- Read the Cypress code coverage guide
- Read "Code Coverage by Parcel Bundler" blog post
- Read "Combined End-to-end and Unit Test Coverage"
- If you are using React, check out @cypress/instrument-cra
Full examples we use for testing in this repository:
- examples/backend only instruments the backend Node server and saves the coverage report
- examples/fullstack instruments and merges backend, e2e and unit test coverage into a single report
- examples/before-all-visit checks if code coverage works when
cy.visitis made once in thebeforehook - examples/before-each-visit checks if code coverage correctly keeps track of code when doing
cy.visitbefore each test - examples/one-spec.js confirms that coverage is collected and filtered correctly if the user only executes a single Cypress test
- examples/ts-example uses Babel + Parcel to instrument and serve TypeScript file
- examples/use-webpack shows Webpack build with source maps and Babel
Look up the list of examples under GitHub topic cypress-code-coverage-example
- cypress-io/cypress-example-todomvc-redux is a React / Redux application with 100% code coverage.
- cypress-io/cypress-example-realworld shows how to collect the coverage information from both back and front end code and merge it into a single report. The E2E test step runs in parallel in several CI containers, each saving just partial test coverage information. Then a merge job runs taking artifacts and combining coverage into the final report to be sent to an exteral coverage as a service app.
- bahmutov/code-coverage-webpack-dev-server shows how to collect code coverage from an application that uses webpack-dev-server.
- bahmutov/code-coverage-vue-example collects code coverage for Vue.js single file components.
- lluia/cypress-typescript-coverage-example shows coverage for React App that uses TypeScript. See discussion in issue #19.
- bahmutov/cypress-and-jest shows how to run Jest unit tests and Cypress unit tests, collecting code coverage from both test runners, and then produce merged report.
- rootstrap/react-redux-base shows an example with a realistic Webpack config. Instruments the source code using
babel-plugin-istanbulduring tests. - bahmutov/cypress-angular-coverage-example forked from skylock/cypress-angular-coverage-example shows Angular 8 + TypeScript application with instrumentation done using istanbul-instrumenter-loader.
- bahmutov/testing-react shows how to get code coverage for a React application created using CRA v3 without ejecting
react-scripts. - bahmutov/cra-ts-code-coverage-example instruments TypeScript React application on the fly without ejecting
react-scriptsby using @cypress/instrument-cra. - bahmutov/next-and-cypress-example shows how to get backend and frontend coverage for a Next.js project. Uses middleware/nextjs.js.
- akoidan/vue-webpack-typescript Pure webpack config with vue + typescript with codecov reports. This setup uses babel-loader with TS checker as a separate thread.
- bahmutov/code-coverage-subfolder-example shows how to instrument
appfolder usingnyc instrumentas a separate step before running E2E tests - bahmutov/docker-with-cypress-included-code-coverage-example runs tests inside pre-installed Cypress using cypress/included:x.y.z Docker image and reports code coverage.
- bahmutov/app-in-docker-coverage-example shows an app running inside a Docker container, while Cypress runs on the local machine. Cypress can still discover the source files before generating the report.
Change the plugins file cypress/plugins/index.js
// BEFORE module.exports = (on, config) => { on('task', require('@cypress/code-coverage/task')) } // AFTER module.exports = (on, config) => { require('@cypress/code-coverage/task')(on, config) // IMPORTANT to return the config object // with the any changed environment variables return config }Tip: we include plugins.js file you can point at from your code in simple cases. From your cypress.json file:
{ "pluginsFile": "node_modules/@cypress/code-coverage/plugins", "supportFile": "node_modules/@cypress/code-coverage/support" }See examples/use-plugins-and-support
This plugin uses debug module to output additional logging messages from its task.js file. This can help with debugging errors while saving code coverage or reporting. In order to see these messages, run Cypress from the terminal with environment variable DEBUG=code-coverage. Example using Unix syntax to set the variable:
$ DEBUG=code-coverage npm run dev ... code-coverage reset code coverage in interactive mode +0ms code-coverage wrote coverage file /code-coverage/.nyc_output/out.json +28ms code-coverage saving coverage report using command: "nyc report --report-dir ./coverage --reporter=lcov --reporter=clover --reporter=json" +3msYou can test changes locally by running tests and confirming the code coverage has been calculated and saved.
npm run test:ci # now check generated coverage numbers npx nyc report --check-coverage true --lines 80 npx nyc report --check-coverage true --lines 100 --include cypress/about.js npx nyc report --check-coverage true --lines 100 --include cypress/unit.jsTip: use check-code-coverage for stricter code coverage checks than nyc report --check-coverage allows.
You can validate links in Markdown files in this directory by executing (Linux + Mac only) script
npm run check:markdownThis project is licensed under the terms of the MIT license.


