Setting up Cypress Code Coverage
By Hamid Akhtar, Community Contributor - February 2, 2023
Software engineering places a lot of emphasis on testing. It allows for quicker code delivery while ensuring that changes to our application are completed successfully. Before the application going live, it makes sure that any unforeseen defects are quickly discovered.
How can we know whether our testing is enough, though? Are certain aspects of the application still being tested?
During end-to-end testing, Cypress code coverage becomes crucial. In the following sections, we’ll figure out how code coverage in Cypress is a handy solution.
Importance of Cypress Code Coverage
Code coverage is a term used in testing to describe how well a source code is being executed. This reveals the sections of the source code that are executed during test execution.
Code coverage is not a standard feature of Cypress testing library. Hence, Cypress code coverage requires some setup and configuration.
As additional tests are generated and stacked, the necessity of testing particular application components may be questioned. We can look at metrics such as functional, statement, branches, condition, and line by employing code coverage.
- Function coverage: It measures how many of the defined functions have been called.
- Statement Coverage: Used to track how many program statements have been run.
- Branch Coverage: A measure of how many branches in a control structure have been successfully executed.
- Condition Coverage: Used to observe boolean subexpressions that are examined for true and false.
- Line Coverage: Counts the number of lines of source code that have been tested.
Follow-Up Read: Measuring Code Coverage
What are the Benefits of Code Coverage?
- It can help find and get rid of dead code.
- QA might benefit from locating missing or untested test cases.
- It can keep an eye on the parts of the source code that are not currently being recorded and check the health and integrity of the code.
Setting up Code Coverage in Cypress
It takes three steps to set up Cypress code coverage:
- To find out which statements are being executed, we must first instrument our code.
- For those statements to be executed, we must run the instrumented code.
- Report the results and check the execution, if any.
1. Instrumentation
The instrumentation procedure includes the following steps: calculating the number of lines of source code that were executed during testing, parsing it to identify all functions, statements, and branches, and finally adding counters to the code. These counters indicate the frequency of execution of these statements, functions, and branches.
// square.js function square (num) { return num**2 } module.exports = { square }
The source code for instrumenting the code above might resemble this.
const c = (window.__coverage__ = { // we have just one function, thus [0] f: [0], // we have three statements, thus [0,0,0] s: [0, 0, 0], })
For our program, let’s create a test.
// square.spec.js const { square } = require('./square') it('squares a number', () => { expect(square(5)).to.equal(25) })
The aforementioned test will add counters to the coverage object that may resemble this.
const c = (window.__coverage__ = { f: [1], s: [1, 1, 1] }) // Our function is defined in the first statement, which is incremented. c.s[0]++ function square(num) { c.f[0]++ c.s[1]++ return num**2 } // 3rd statement is called and incremented as well c.s[2]++ module.exports = { square }
- In this instance, our test covers 100% of the code.
- The created report for this coverage object will be preserved in a human-readable format.
- Cypress does not instrument our code; instead, we must do so manually using either the nyc or the babel-plugin-istanbul as part of the code translation pipeline (a command-line interface to istanbul).
2. Installation & Configuration
- Let’s install and set up each of our required dependencies.
- You can instrument your code with Istanbul coverage using the babel plugin “babel-plugin-istanbul.” It is compatible with Karma and Mocha (which is used by Cypress as well)
- A coverage information summary API is available from istanbul-lib-coverage, which can read and integrate coverage data.
- An HTML file is one of the several output formats for a code coverage report from the Istanbul command line interface nyc.
sh$ yarn add babel-plugin-istanbul istanbul-lib-coverage nyc
Install the Cypress Code Coverage Plugin
sh$ yarn add cypress @cypress/code-coverage
Configure.babelrc (if you don’t already have one, create one)
{ "plugins": ["istanbul"] }
Make a nyc configuration file. In this instance, I want to examine the coverage for both.js and .vue
{ "extension": [".js", ".vue"] }
3. Setup for the Cypress Code Coverage Plugin
To use the Cypress Code Coverage plugin after adding Cypress to your project, you must configure the Cypress plugin file, located at cypress/plugin/index.js.
import '@cypress/code-coverage/support'
module.exports = (on, config) => { on('task', require('@cypress/code-coverage/task')) }
Let’s take a time to ponder some philosophical ideas now that everything is set up. Should we try to cover everything? Though it may seem wonderful, achieving 100% code coverage does not imply that we are bug-free.
You’ll see that this test contains zero assertions:
it('generates a random fact', () => { cy .visit('/') cy .get('button') .click() });
However, there are many things that might go wrong in our app. Any number of things may go wrong, including our layout, improper character rendering, and a malfunctioning API. Nevertheless, our test covered every possible scenario.
We’re “taking a walk” through our app, but we’re not truly asserting the values it brings us back. This is something to bear in mind while writing tests that incorporate test coverage.
- Finding areas of a project that are not covered by tests and navigating it can be made easier using code coverage.
- It is an excellent navigational tool that is quick to set up and offers many benefits.
The image below shows additional counters and instructions that should be present in the JavaScript resources of your application if it has been properly instrumented.
When viewing the “Application under test iframe,” you will notice the window.__coverage__ object.
If you have instrumented the code for your application and saw the window. __coverage__ object, this plugin will save the coverage into the.nyc_output folder and generate reports once the tests have been completed (even in the interactive mode). The folder coverage/lcov-report contains the LCOV and HTML report.
It is recommend that you go through these to gain a greater understanding of the subject:
- Check out the instrumentation code guide for Cypress.
- View a webinar on Code coverage
- View the code coverage videos on Cypress Tips & Tricks.
App vs Unit Tests
A web application needs to be instrumented. This means that you should instrument the requests for index.html whenever the test uses the cy.visit(‘localhost:3000’) function. Often, you need to add the babel-plugin-istanbul to your pipeline somewhere.
Unit testing is testing individual functions from your application code by importing them straight into Cypress spec files. Cypress can instrument this process for you. Check out the section on instrument unit tests.
- The coverage folder contains results in various forms, and the raw coverage data is kept in the.nyc_output folder.
- The coverage statistics are available for your inspection.
- Since nyc is dependent on this plugin, it should be immediately accessible.
Here are a few typical instances:
# 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=lcov
Closing Notes
So you can now readily understand how to generate code coverage from running E2E tests locally. You can use your Continuous Integration system to put this idea into practice, and the nyc command enables producing reports in a number of different formats. So that you may monitor your Cypress code coverage Trend on your CI system.
You may become more assured in the calibre of the product as a result. You can easily manage the test coverage. The objective is to improve code quality, correct?
- For extensive automated testing, many organizations opt for BrowserStack as one of the leading cloud-based testing platforms.
- The major advantage is not having to to change or alter your test scripts
- Running cross-browser tests across different browser-device combinations simultaneously using Parallel Testing with Cypress further accelerates the testing process.
- Cypress Safari testing is now supported for WebKit on BrowserStack Automate. QA teams can easily test their web applications on Safari.