Integrating Mochawesome reporter with Cypress
Cypress has made a revolution in software end-to-end testing. Having a set of killer features, it delivers such a smooth experience to developers and testing engineers, especially compared to older tools like Selenium, that makes it win any competition. Since the first public release of Cypress, I started to use and promote it on every project I support.
If you want to use Cypress on your project you might be interested in generating test reports. Since Cypress is built on top of Mocha testing framework, it supports the same test reporters as Mocha does. One of the most popular reporters for Mocha is Mochawesome. It provides an interactive HTML page together with JSON file with all the details about your test suites. This is the most user-friendly report I’ve ever seen.
The Problem
Since the version 3.0.0 Cypress executes each spec in isolation. This leads to Mocha generating a separate test report for each spec. Thus, there’s no out-of-the-box solution to generate one mochawesome report for all your specs.
Fortunately, this problem is solvable and below I will show you how.
A Solution
To be able to generage one big mochawesome report for all Cypress specs I’ve released a special npm package - mochawesome-merge. From the name you can already guess that it’s responsibility is to merge multiple mochawesome reports together. And that’s correct.
Mochawesome Configuration
I’m going to explain how to integrate mochawesome-merge into an existing Cypress configuration. The idea is to configure Cypress to generate many test reports and then run a special command to merge them.
Let’s start with installing the mochawesome reporter.
$ npm install mochawesome -D
Once installed, let’s configure Cypress to use the reporter.
Open cypress.json
file and add "reporter": "mochawesome"
to it.
{
"reporter": "mochawesome"
}
This will generate test reports within the mochawesome-report
directory under your project root every time you run your cypress tests. But if you run tests now you will be able to see a report only for one of your specs — the one that was run the latest. Reports for all the other tests are being overridden and lost. That’s not what we want to achieve, so let’s disable the mochawesome’s overwrite
property.
{
"reporter": "mochawesome",
"reporterOptions": {
"overwrite": false
}
}
Now if you run your tests you will be able to see many reports being generated under the mochawesome-report
directory. For each spec two files mochawesomeXXX.json
and mochawesomeXXX.html
are being created, where XXX
is the numeric count. Having 3 digits after the name puts a limitation to have only less than 1000 spec files. But that’s enough for most of the projects.
One more limitation is that those numbers are just numbers and they are not related to the spec name, so there’s no way to have a mnemonic link between the spec file and the test report name. It means that if you wish to have valid test reports, it’s impossible to run only specific Cypress specs — you will need to run them all together. And don’t forget to clean the mochawesome-report
directory before running the tests — to prevent data corruption.
There’s one optimization we can do right now. Since Mochawesome generates a lot of html reports and we will consume only one report for all the specs, these intermediate reports are redundant and can be disabled. Let’s be more explicit and also mark json
reports as enabled.
{
"reporter": "mochawesome",
"reporterOptions": {
"overwrite": false,
"html": false,
"json": true
}
}
Merging Reports
Ok, we’ve configured Mochawesome to generate one json report per spec file. Now let’s merge these reports into one big report. For that we will use mochawesome-merge.
First, install the package.
$ npm install mochawesome-merge --save-dev
mochawesome-merge
comes with JavaScript SDK as well as CLI.
It’s up to you, which of the interface you prefer.
Here we will be using JavaScript SDK.
Basically, it provides a function that accepts some optional config and returns a promise that resolves to a merged Mochawesome JSON report.
const { merge } = require('mochawesome-merge')
merge().then(report => {
console.log(report)
})
We need to execute this function after Cypress finishes running all tests.
Fortunately, Cypress does not throw when a test fails. This makes our code simpler.
We don’t need to handle errors to be sure that mochawesome-merge
is executed whatever the test result is.
const cypress = require('cypress')
const { merge } = require('mochawesome-merge')
async function runTests() {
await cypress.run()
const jsonReport = await merge()
}
runTests()
To run this code, let’s put it in the scripts/cypress.js
file and configure an npm script in package.json
.
{
"scripts": {
"cy:run": "node scripts/cypress.js"
}
}
Now if you run npm run cy:run
this code will work, but JSON reports will be accumulated within the mochawesome-report
directory.
Let’s modify the function to clean the directory before running tests.
For this I used fs-extra
npm package.
You can choose other solutions, like running this in an npm pre- hook or just using another library.
Let’s make another improvement and exit with non-zero status code when tests fail.
const cypress = require('cypress')
const fse = require('fs-extra')
const { merge } = require('mochawesome-merge')
async function runTests() {
await fse.remove('mochawesome-report') // remove the report folder
const { totalFailed } = await cypress.run() // get the number of failed tests
const jsonReport = await merge() // generate JSON report
process.exit(totalFailed) // exit with the number of failed tests
}
runTests()
Generating HTML Report
Until now we did not use the JSON report generated by mochawesome-merge
.
We just throw it away each time the tests run.
Let’s use it to generate a beautiful Mochawesome HTML report.
For this we will use mochawesome-report-generator
npm package.
This package is used internally by Mochawesome (both packages are maintained by the same author).
We will use it here as well.
Let’s first install it.
$ npm install mochawesome-report-generator --save-dev
And here’s what we add to our code.
const cypress = require('cypress')
const fse = require('fs-extra')
const { merge } = require('mochawesome-merge')
+ const generator = require('mochawesome-report-generator')
async function runTests() {
await fse.remove('mochawesome-report')
const { totalFailed } = await cypress.run()
const jsonReport = await merge()
+ await generator.create(jsonReport)
process.exit(totalFailed)
}
runTests()
Now, if you run the command you will get a nice-looking html report under mochawesome-report/mochawesome.html
path.
Future Improvements
mochawesome-report-generator
accepts multiple configuration options that allow you to control how your report is being generated.
For example, there’s an inline
option that bakes all static assets within the html report file. This is useful if you want to share this report with someone and don’t want to deal with its dependencies.
Also, you may find it useful to log a link to the generated report. Depending on your terminal you will have an ability to open the report by clicking on a link rather than opening a folder by yourself.
I hope this guide helped you to integrate Mochawesome into your Cypress setup. Here I have described the way I did it on my project. In case of any questions I will be happy to help.