Skip to content

Commit

Permalink
feat: save unit test code coverage from specs
Browse files Browse the repository at this point in the history
  • Loading branch information
bahmutov committed May 17, 2019
1 parent 8fb2c91 commit 0f55e32
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
33 changes: 33 additions & 0 deletions README.md
Expand Up @@ -32,6 +32,39 @@ If your application is loaded Istanbul-instrumented source code, then the covera

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

## Instrument unit tests

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

```js
const browserify = require('@cypress/browserify-preprocessor')

module.exports = (on, config) => {
on('task', require('cypress-istanbul/task'))

// tell Cypress to use .babelrc when bundling spec code
const options = browserify.defaultOptions
options.browserifyOptions.transform[1][1].babelrc = true
on('file:preprocessor', browserify(options))
}
```

Install the plugin

```
npm i -D babel-plugin-istanbul
```

and set in your `.babelrc` file

```rc
{
"plugins": ["istanbul"]
}
```

Now the code coverage from spec files will be combined with end-to-end coverage.

## Examples

- [Demo battery app](https://github.com/bahmutov/demo-battery-api/tree/bundle) branch "bundle"
Expand Down
26 changes: 24 additions & 2 deletions support.js
Expand Up @@ -11,13 +11,35 @@ afterEach(() => {
// because the entire "window" object is about
// to be recycled by Cypress before next test
cy.window().then(win => {
if (win.__coverage__) {
cy.task('combineCoverage', win.__coverage__)
// if application code has been instrumented, the app iframe "window" has an object
const applicationSourceCoverage = win.__coverage__

if (applicationSourceCoverage) {
cy.task('combineCoverage', applicationSourceCoverage)
}
})
})

after(() => {
const specFolder = Cypress.config('integrationFolder')
const supportFolder = Cypress.config('supportFolder')

// if spec bundle has been instrumented (using Cypress preprocessor)
// then we will have unit test coverage
// NOTE: spec iframe is NOT reset between the tests, so we can grab
// the coverage information only once after all tests have finished
const unitTestCoverage = window.__coverage__
if (unitTestCoverage) {
// remove coverage for the spec files themselves,
// only keep "external" application source file coverage
const coverage = Cypress._.omitBy(
window.__coverage__,
(fileCoverage, filename) =>
filename.startsWith(specFolder) || filename.startsWith(supportFolder)
)
cy.task('combineCoverage', coverage)
}

// when all tests finish, lets generate the coverage report
cy.task('coverageReport')
})

0 comments on commit 0f55e32

Please sign in to comment.