Skip to content

Commit 0f55e32

Browse files
committed
feat: save unit test code coverage from specs
1 parent 8fb2c91 commit 0f55e32

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

README.md

+33
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,39 @@ If your application is loaded Istanbul-instrumented source code, then the covera
3232

3333
![Coverage report](images/coverage.jpg)
3434

35+
## Instrument unit tests
36+
37+
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](https://github.com/istanbuljs/babel-plugin-istanbul) for example. Put the following in `cypress/plugins/index.js` file to use `.babelrc` file
38+
39+
```js
40+
const browserify = require('@cypress/browserify-preprocessor')
41+
42+
module.exports = (on, config) => {
43+
on('task', require('cypress-istanbul/task'))
44+
45+
// tell Cypress to use .babelrc when bundling spec code
46+
const options = browserify.defaultOptions
47+
options.browserifyOptions.transform[1][1].babelrc = true
48+
on('file:preprocessor', browserify(options))
49+
}
50+
```
51+
52+
Install the plugin
53+
54+
```
55+
npm i -D babel-plugin-istanbul
56+
```
57+
58+
and set in your `.babelrc` file
59+
60+
```rc
61+
{
62+
"plugins": ["istanbul"]
63+
}
64+
```
65+
66+
Now the code coverage from spec files will be combined with end-to-end coverage.
67+
3568
## Examples
3669

3770
- [Demo battery app](https://github.com/bahmutov/demo-battery-api/tree/bundle) branch "bundle"

support.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,35 @@ afterEach(() => {
1111
// because the entire "window" object is about
1212
// to be recycled by Cypress before next test
1313
cy.window().then(win => {
14-
if (win.__coverage__) {
15-
cy.task('combineCoverage', win.__coverage__)
14+
// if application code has been instrumented, the app iframe "window" has an object
15+
const applicationSourceCoverage = win.__coverage__
16+
17+
if (applicationSourceCoverage) {
18+
cy.task('combineCoverage', applicationSourceCoverage)
1619
}
1720
})
1821
})
1922

2023
after(() => {
24+
const specFolder = Cypress.config('integrationFolder')
25+
const supportFolder = Cypress.config('supportFolder')
26+
27+
// if spec bundle has been instrumented (using Cypress preprocessor)
28+
// then we will have unit test coverage
29+
// NOTE: spec iframe is NOT reset between the tests, so we can grab
30+
// the coverage information only once after all tests have finished
31+
const unitTestCoverage = window.__coverage__
32+
if (unitTestCoverage) {
33+
// remove coverage for the spec files themselves,
34+
// only keep "external" application source file coverage
35+
const coverage = Cypress._.omitBy(
36+
window.__coverage__,
37+
(fileCoverage, filename) =>
38+
filename.startsWith(specFolder) || filename.startsWith(supportFolder)
39+
)
40+
cy.task('combineCoverage', coverage)
41+
}
42+
2143
// when all tests finish, lets generate the coverage report
2244
cy.task('coverageReport')
2345
})

0 commit comments

Comments
 (0)