-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combining coverage from 2 test runs? #2418
Comments
@DmitriiAbramov do we have anything for this? I think this could be pretty handy if we decide to kill our internal runner. |
it's actually pretty easy to do with istanbul as long as you have a |
Just in case someone needs step by step to do this (I literally combined my coverage report after finally stumbled upon here).
I also do the code coverage config thing from
Of course, don't forget to install the dependencies that you need for |
Finally tackled this today. Our use case was a bit different, as files tested were exactly the same, under exactly the same paths but took different code paths due to environment variables being set and running the application in different package.json | jest.config.json
And we had to make some changes to our test command too, there is probably a better way but a quick 5s google search did not yield any results on how to generate coverages with different file names package.json
mapCoverage.js had to have some changes done too, since we're reading from two coverage files with the same paths, instead of one with different paths. mapCoverage.js
@DmitriiAbramov @cpojer Thanks for the help! |
@DmitriiAbramov shall we make mapCoverage into a |
@cpojer might be a good idea. Istanbul already provides everything needed for that, but it's not documented and requires some additional configuration. were you thinking about something like this? const {mergeCoverage} = require('jest-map-coverage');
merge(
'file1.json',
'file2.json',
).replacePaths(path => path.toLowerCase()); |
I use https://www.npmjs.com/package/istanbul-merge to merge istanbul reports - with that and #2861, it should be trivial. |
thanks @tmayr for sharing. that works for me! actually var istanbul = require('istanbul'),
collector = new istanbul.Collector(),
reporter = new istanbul.Reporter(),
sync = false;
const countries = ['chile', 'peru'];
countries.forEach(country => {
const coverage = require(`../coverage/coverage-${country}-final.json`);
collector.add(coverage);
});
reporter.addAll([ 'text', 'lcov', 'clover' ]);
reporter.write(collector, sync, function () {
console.log('All reports generated');
}); Above code should work. but I"m getting |
For everyone who struggles with these nowadays and receives errors like
or
For some reason Istanbul tooling not working with jest-generated coverage JSONs because of some weird "data" key that appears in some entries of coverage JSONs files. I.e. these entries in the same coverage json.
I solved this by just deleting this "data" key and passing its value directly to the file-path key. Here's my full 'mapCoverage' function. /* eslint-disable import/no-extraneous-dependencies */
const libCoverage = require('istanbul-lib-coverage');
const { createReporter } = require('istanbul-api');
const integrationCoverage = require('../coverage-integration/coverage-final.json');
const unitCoverage = require('../coverage-unit/coverage-final.json');
const normalizeJestCoverage = (obj) => {
const result = obj;
Object.entries(result).forEach(([k, v]) => {
if (v.data) result[k] = v.data;
});
return result;
};
const map = libCoverage.createCoverageMap();
map.merge(normalizeJestCoverage(integrationCoverage));
map.merge(normalizeJestCoverage(unitCoverage));
const reporter = createReporter();
reporter.addAll(['json', 'lcov', 'text']);
reporter.write(map); I assume that whole Lerna powered Istanbul repository is the latest version, so, why doesn't it assume coverage files to have 'data' key? And what this 'data' key is? Why it only appears in some entries? @cpojer if you have a little bit of time, can you please give any comments? Maybe there's a newer version of istanbul exists that respects this "data" key or something? At least I couldn't find anything. Thank you very much! |
We had this issue as well, digging into where the data attribute was coming from it was a typings.d.ts file to allow importing of .json modules:
Removing this file, and updating the Typescript ^2.9.2 tsconfig to import JSON fixed our issues
|
FYI: More explanation on this other issue message. |
If you're using istanbul, the CLI seems to automatically merge any JSON files you use for you:
With that my map coverage command just needs to clean up the JSON from Jest as described by @fahrenq
|
https://artsyproduct.atlassian.net/browse/PLATFORM-1136 Problem: One part of the product health matrix story [spike][spike] is code coverage for each service. However, there is no pattern at Artsy for measuring code coverage for Javascript applications. While there are existing tools out there for tracking and reporting code coverage, such as [istanbul.js][istanbul-js], [coveralls][coveralls], and [codecov][codecov], the complexities: 1. A multi-runner test suite (jest and mocha), and 2. A Circle CI -> Docker -> Docker test runtime have resulted in a tough problem to solution around. Solution: After spending a lot of time trying to get Coveralls instrumentation to work, we pivoted to using Codecov. At a high level, this commit does the following: 1. Updates our calls to `jest` and `mocha` to write code coverage information to a `.nyc_output` directory (default for nyc/istanbul) 2. Manipulates the `jest` coverage information to be compatible with `mocha` coverage information via a JS script. See [motivating GH issue][gh-issue]. 3. Merges the `jest` and `mocha` coverage information together using the `nyc` CLI 4. Introduces a bash executable provided by codecov to instrument the merged information to codecov Co-authored-by: Kieran Gillen <[email protected]> [spike]:https://artsyproduct.atlassian.net/browse/PLATFORM-1098 [istanbul-js]:https://github.com/istanbuljs/nyc [coveralls]:https://coveralls.io/ [codecov]:https://codecov.io/gh/artsy/positron/ [gh-issue]:jestjs/jest#2418 Add coveralls and mocha-lcov-report packages via `yarn add --dev` Add Istanbul CLI, nyc, via `yarn add --dev nyc` * nyc is a CLI for a code coverage reporting tool Downgrade coveralls to 2.12 Attempt to get coverage reporting working - add yarn coverage - use prefix mocha with `nyc` - attempt to output jest coverage data in .nyc_output - create a coverage mapper that removes the incompatible “data” key from Jest’s built-in `—coverage` output Try wrapping jest in nyc to generate coverage data Revert "Try wrapping jest in nyc to generate coverage data" This reverts commit 0600861. Remove custom placement of jest coverage data Try ignoring src/client/collections from coverage collection Revert "Downgrade coveralls to 2.12" This reverts commit 04dee17. Install codecov to run on Docker * Add bash to Dockerimage * Explicity pass in commit hash as git isn’t present in the container * Move manipulated jest coverage back to .nyc_output + possible improvement: pass directory directly to Reporter * Tell jest to write all of it’s coverage info to .nyc Restructure coverage build pipeline Break up components of codecov installation into component scripts, and call components from a "main" `publish-coverage` script. * Specify the root path of the application in hopes that codecov does better in the absence of Git Wrap `jest` with options into a script/jest.sh * Mimics pattern used to run mocha tests Remove coveralls in favor of codecov Report test coverage from script/test.sh Because we're in docker, test coverage needs to be reported within the same container; otherwise, we'll have to figure out how to share assets across build steps. Because we're `set -e`ing this script, code coverage shouldn't be instrumented unless the entire test suite passes, which the typical behavior of code coverage tooling. Inject the CODECOV_TOKEN into call to `hokusai test` * Token is required to authenticate with Codecov * Add token ENV key name to .env.test to provide a place to document it's use + not needed during typical dev, only useful on CI Add codecov badge to README Host codecov locally * Add script/codecov * Add coverage.lcov to .gitignore * Remove obsolete install-codecov yarn script
https://artsyproduct.atlassian.net/browse/PLATFORM-1136 Problem: One part of the product health matrix story [spike][spike] is code coverage for each service. However, there is no pattern at Artsy for measuring code coverage for Javascript applications. While there are existing tools out there for tracking and reporting code coverage, such as [istanbul.js][istanbul-js], [coveralls][coveralls], and [codecov][codecov], the complexities: 1. A multi-runner test suite (jest and mocha), and 2. A Circle CI -> Docker -> Docker test runtime have resulted in a tough problem to solution around. Solution: After spending a lot of time trying to get Coveralls instrumentation to work, we pivoted to using Codecov. At a high level, this commit does the following: 1. Updates our calls to `jest` and `mocha` to write code coverage information to a `.nyc_output` directory (default for nyc/istanbul) 2. Manipulates the `jest` coverage information to be compatible with `mocha` coverage information via a JS script. See [motivating GH issue][gh-issue]. 3. Merges the `jest` and `mocha` coverage information together using the `nyc` CLI 4. Introduces a bash executable provided by codecov to instrument the merged information to codecov Co-authored-by: Kieran Gillen <[email protected]> [spike]:https://artsyproduct.atlassian.net/browse/PLATFORM-1098 [istanbul-js]:https://github.com/istanbuljs/nyc [coveralls]:https://coveralls.io/ [codecov]:https://codecov.io/gh/artsy/positron/ [gh-issue]:jestjs/jest#2418
https://artsyproduct.atlassian.net/browse/PLATFORM-1136 Problem: One part of the product health matrix story [spike][spike] is code coverage for each service. However, there is no pattern at Artsy for measuring code coverage for Javascript applications. While there are existing tools out there for tracking and reporting code coverage, such as [istanbul.js][istanbul-js], [coveralls][coveralls], and [codecov][codecov], the complexities: 1. A multi-runner test suite (jest and mocha), and 2. A Circle CI -> Docker -> Docker test runtime have resulted in a tough problem to solution around. Solution: After spending a lot of time trying to get Coveralls instrumentation to work, we pivoted to using Codecov. At a high level, this commit does the following: 1. Updates our calls to `jest` and `mocha` to write code coverage information to a `.nyc_output` directory (default for nyc/istanbul) 2. Manipulates the `jest` coverage information to be compatible with `mocha` coverage information via a JS script. See [motivating GH issue][gh-issue]. 3. Merges the `jest` and `mocha` coverage information together using the `nyc` CLI 4. Introduces a bash executable provided by codecov to instrument the merged information to codecov Co-authored-by: Kieran Gillen <[email protected]> [spike]:https://artsyproduct.atlassian.net/browse/PLATFORM-1098 [istanbul-js]:https://github.com/istanbuljs/nyc [coveralls]:https://coveralls.io/ [codecov]:https://codecov.io/gh/artsy/positron/ [gh-issue]:jestjs/jest#2418
https://artsyproduct.atlassian.net/browse/PLATFORM-1136 Problem: One part of the product health matrix story [spike][spike] is code coverage for each service. However, there is no pattern at Artsy for measuring code coverage for Javascript applications. While there are existing tools out there for tracking and reporting code coverage, such as [istanbul.js][istanbul-js], [coveralls][coveralls], and [codecov][codecov], the complexities: 1. A multi-runner test suite (jest and mocha), and 2. A Circle CI -> Docker -> Docker test runtime have resulted in a tough problem to solution around. Solution: After spending a lot of time trying to get Coveralls instrumentation to work, we pivoted to using Codecov. At a high level, this commit does the following: 1. Updates our calls to `jest` and `mocha` to write code coverage information to a `.nyc_output` directory (default for nyc/istanbul) 2. Manipulates the `jest` coverage information to be compatible with `mocha` coverage information via a JS script. See [motivating GH issue][gh-issue]. 3. Merges the `jest` and `mocha` coverage information together using the `nyc` CLI 4. Introduces a bash executable provided by codecov to instrument the merged information to codecov Co-authored-by: Kieran Gillen <[email protected]> [spike]:https://artsyproduct.atlassian.net/browse/PLATFORM-1098 [istanbul-js]:https://github.com/istanbuljs/nyc [coveralls]:https://coveralls.io/ [codecov]:https://codecov.io/gh/artsy/positron/ [gh-issue]:jestjs/jest#2418
Just to summarize. I've used different suggestions here and there and this is the final script that works for me as of today that allows to combine 2 coverage reports in json format into one combined report (with set of formats: json, lcov). /*
yarn tsn-script ./scripts/mergeCoverage.ts --report ./coverage0/coverage-final.json --report ./coverage1/coverage-final.json
*/
import * as fs from 'fs-extra'
import * as yargs from 'yargs'
const { createCoverageMap } = require('istanbul-lib-coverage')
const { createReporter } = require('istanbul-api');
main().catch(err => {
console.error(err)
process.exit(1)
})
async function main () {
const argv = yargs
.options({
report: {
type: 'array', // array of string
desc: 'Path of json coverage report file',
demandOption: true,
},
reporters: {
type: 'array',
default: ['json', 'lcov'],
}
})
.argv
const reportFiles = argv.report as string[]
const reporters = argv.reporters as string[]
const map = createCoverageMap({})
reportFiles.forEach(file => {
const r = fs.readJsonSync(file)
map.merge(r)
})
const reporter = createReporter();
// reporter.addAll(['json', 'lcov', 'text']);
// reporter.addAll(['json', 'lcov']);
reporter.addAll(reporters)
reporter.write(map)
console.log('Created a merged coverage report in ./coverage')
} |
I noticed that it can be pretty difficult to try and merge multiple coverage data from various tests. It is clear that some people have issues with trying to do this as well. https://www.rapitasystems.com/blog/merging-coverage-data-multiple-test-runs |
How do you check-coverage after generating a merged report? |
One of the issues I've run into (solved through some unknown means by CodeCov, see "Merging Reports") when trying to combine runs from different machines is differing path prefixes (especially *nix vs Windows machines). I don't know of a simple way to combine the outputs under that differing path prefix circumstance. And without that merge, the coverage metric will continually flip-flip between wildly incorrect values. |
Thanks @OshriBa, @rivy. I was asking about enforcing coverage thresholds on a merged report. I was able to get merged coverage from jest + mocha + newman tests with the help of this thread. However, running nyc check-coverage on the merged report failed with |
@fahrenq hey did you figure this out within Lerna? We have Angular 1 along side Angular 8 and jest, and we're getting that weird |
@mcblum Sorry, I completely forgot context as by now. Good luck :) |
All good, thank you! |
Since |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
I'm currently running tests in two different app settings (we have different tests depending on which country the application is launched).
I'd love to have one coverage with both runs combined as the code goes through different parts on each run.
Is this something remotely possible to do?
What would be the best practice in this scenarios?
The text was updated successfully, but these errors were encountered: