Jest: Jest collects coverage for unrelated to project files

Created on 24 May 2016  Â·  10Comments  Â·  Source: facebook/jest

I placed mocks into __mocks__ directory and jest collects coverage for it.

➜  FOO git:(master) ✗ jest fooooooooo-smart --coverage
Using Jest CLI v12.0.2, jasmine2
 PASS  src/baaaaaaaaaar/fooooooooo/__tests__/fooooooooo-smart.js (1.141s)
8 tests passed (8 total in 1 test suite, run time 2.328s)
----------------------------------------|----------|----------|----------|----------|----------------|
File                                    |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
----------------------------------------|----------|----------|----------|----------|----------------|
 jestSupport/                           |      100 |      100 |      100 |      100 |                |
  env.js                                |      100 |      100 |      100 |      100 |                |
 src/baaaaaaaaaar/fooooooooo/           |      100 |      100 |      100 |      100 |                |
  fooooooooo-smart.js                   |      100 |      100 |      100 |      100 |                |
 src/baaaaaaaaaar/fooooooooo/__mocks__/ |    84.62 |        0 |       75 |      100 |                |
  react-native.js                       |    42.86 |        0 |        0 |      100 |                |
  react-redux.js                        |      100 |      100 |      100 |      100 |                |
  fooooooooo-duck.js                    |      100 |      100 |      100 |      100 |                |
  fooooooooo-dumb.js                    |      100 |      100 |      100 |      100 |                |
----------------------------------------|----------|----------|----------|----------|----------------|
All files                               |    93.65 |        0 |    86.67 |      100 |                |
----------------------------------------|----------|----------|----------|----------|----------------|

*(jestSupport is a temporary fix)

for example, __mocks__/react-native.js:

export * from 'react-native-mock/mock';

Yeah, jest don't has config for excluding coverage from specific files...
Only way to exclude __mocks__ is to list all files in the project into collectCoverageOnlyFrom. But ... This is pretty fatiguing :(

I can list all js files with shell oneliner find src -name '*.js' | grep -Ev '(__tests__)|(__mocks__)'

But including __mocks__ directory in the coverage report - this is a bug, isn't it?

Most helpful comment

Well at least you know your mocks are being used

All 10 comments

I have the same issue in _12.1.1_. I did set up the rootDir and it seems to be ignored by the code coverage suite.

package.json:

{
  "name": "blablabla",
  "version": "0.1.0",
  "description": "",
  "homepage": "",
  "main": "index.js",
  "devDependencies": {
    "babel-cli": "^6.9.0",
    "babel-core": "^6.9.0",
    "babel-jest": "^12.1.0",
    "babel-plugin-inline-package-json": "git+http://...",
    "babel-plugin-transform-runtime": "^6.9.0",
    "babel-polyfill": "^6.9.0",
    "babel-preset-es2015": "^6.8.0",
    "babel-preset-es2015-ie": "^6.6.2",
    "babel-runtime": "^6.6.1",
    "babelify": "^7.3.0",
    "browserify": "^13.0.0",
    "graceful-fs": "^4.1.4",
    "gulp": "^3.9.1",
    "gulp-babel": "^6.1.2",
    "gulp-cli": "^1.2.1",
    "gulp-insert": "^0.5.0",
    "gulp-rename": "^1.2.2",
    "gulp-uglify": "^1.5.3",
    "jasmine-reporters": "^2.1.1",
    "jest-cli": "^12.1.1"
  },
  "scripts": {
    "build": "./build.sh",
    "release": "./build.sh && npm publish",
    "test": "./node_modules/.bin/jest",
    "integration": "./integration.sh"
  },
  "jest": {
    "verbose": false,
    "cacheDirectory": "../jest-cache",
    "coverageThreshold": {
      "global": {
        "branches": 60,
        "functions": 60,
        "lines": 60,
        "statements": 60
      }
    },
    "unmockedModulePathPatterns": [
      "../node_modules/"
    ],
    "setupTestFrameworkScriptFile": "../env-setup.js",
    "rootDir": "./src"
  }
}

result:

$ npm run test

> [email protected] test /Projects/blablabla
> jest

Using Jest CLI v12.1.1, jasmine2, babel-jest
Running 4 test suites...##teamcity[progressStart 'Running Jasmine Tests']
##teamcity[testSuiteStarted name='Iterator' timestamp='2016-05-25T10:38:41.514']
##teamcity[testSuiteStarted name='#constructor' timestamp='2016-05-25T10:38:41.516']
##teamcity[testStarted name='sets array' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.517']
##teamcity[testFinished name='sets array' timestamp='2016-05-25T10:38:41.526']
##teamcity[testStarted name='sets index pointer to 0' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.526']
##teamcity[testFinished name='sets index pointer to 0' timestamp='2016-05-25T10:38:41.529']
##teamcity[testSuiteFinished name='#constructor' timestamp='2016-05-25T10:38:41.530']
##teamcity[testSuiteStarted name='#each' timestamp='2016-05-25T10:38:41.530']
##teamcity[testStarted name='iterates through all list elements one-by-one' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.530']
##teamcity[testFinished name='iterates through all list elements one-by-one' timestamp='2016-05-25T10:38:41.532']
##teamcity[testStarted name='triggers callback with parameters' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.532']
##teamcity[testFinished name='triggers callback with parameters' timestamp='2016-05-25T10:38:41.537']
##teamcity[testSuiteFinished name='#each' timestamp='2016-05-25T10:38:41.539']
##teamcity[testSuiteStarted name='#next' timestamp='2016-05-25T10:38:41.539']
##teamcity[testStarted name='raises the index and returns the current element' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.539']
##teamcity[testFinished name='raises the index and returns the current element' timestamp='2016-05-25T10:38:41.540']
##teamcity[testStarted name='does not go outside the list' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.541']
##teamcity[testFinished name='does not go outside the list' timestamp='2016-05-25T10:38:41.542']
##teamcity[testSuiteFinished name='#next' timestamp='2016-05-25T10:38:41.542']
##teamcity[testSuiteStarted name='#prev' timestamp='2016-05-25T10:38:41.542']
##teamcity[testStarted name='does not go outside the list' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.542']
##teamcity[testFinished name='does not go outside the list' timestamp='2016-05-25T10:38:41.543']
##teamcity[testStarted name='decreases the index and returns the current element' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.544']
##teamcity[testFinished name='decreases the index and returns the current element' timestamp='2016-05-25T10:38:41.545']
##teamcity[testSuiteFinished name='#prev' timestamp='2016-05-25T10:38:41.546']
##teamcity[testSuiteFinished name='Iterator' timestamp='2016-05-25T10:38:41.546']
##teamcity[progressFinish 'Running Jasmine Tests']
 PASS  __tests__/Iterator-test.js (0.578s)
Running 3 test suites...##teamcity[progressStart 'Running Jasmine Tests']
##teamcity[testSuiteStarted name='Promise' timestamp='2016-05-25T10:38:41.593']
##teamcity[testSuiteStarted name='#process' timestamp='2016-05-25T10:38:41.596']
##teamcity[testStarted name='throws error when its resolved' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.597']
##teamcity[testFinished name='throws error when its resolved' timestamp='2016-05-25T10:38:41.606']
##teamcity[testStarted name='throws error when its rejected' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.607']
##teamcity[testFinished name='throws error when its rejected' timestamp='2016-05-25T10:38:41.610']
##teamcity[testStarted name='calls callbacks with arguments' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.611']
##teamcity[testFinished name='calls callbacks with arguments' timestamp='2016-05-25T10:38:41.616']
##teamcity[testSuiteFinished name='#process' timestamp='2016-05-25T10:38:41.617']
##teamcity[testSuiteStarted name='#resolve' timestamp='2016-05-25T10:38:41.617']
##teamcity[testStarted name='calls #process method' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.617']
##teamcity[testFinished name='calls #process method' timestamp='2016-05-25T10:38:41.622']
##teamcity[testStarted name='marks as resolved' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.622']
##teamcity[testFinished name='marks as resolved' timestamp='2016-05-25T10:38:41.624']
##teamcity[testStarted name='sets results' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.624']
##teamcity[testFinished name='sets results' timestamp='2016-05-25T10:38:41.626']
##teamcity[testSuiteFinished name='#resolve' timestamp='2016-05-25T10:38:41.627']
##teamcity[testSuiteStarted name='#reject' timestamp='2016-05-25T10:38:41.627']
##teamcity[testStarted name='calls #process method' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.628']
##teamcity[testFinished name='calls #process method' timestamp='2016-05-25T10:38:41.631']
##teamcity[testStarted name='marks as rejected' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.631']
##teamcity[testFinished name='marks as rejected' timestamp='2016-05-25T10:38:41.632']
##teamcity[testStarted name='sets results' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.633']
##teamcity[testFinished name='sets results' timestamp='2016-05-25T10:38:41.635']
##teamcity[testSuiteFinished name='#reject' timestamp='2016-05-25T10:38:41.635']
##teamcity[testSuiteFinished name='Promise' timestamp='2016-05-25T10:38:41.635']
##teamcity[progressFinish 'Running Jasmine Tests']
 PASS  __tests__/Promise-test.js (0.66s)
Running 2 test suites...##teamcity[progressStart 'Running Jasmine Tests']
##teamcity[testSuiteStarted name='Config' timestamp='2016-05-25T10:38:41.694']
##teamcity[testSuiteStarted name='#setDefaults' timestamp='2016-05-25T10:38:41.696']
##teamcity[testStarted name='sets up the base url' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.697']
##teamcity[testFinished name='sets up the base url' timestamp='2016-05-25T10:38:41.703']
##teamcity[testSuiteFinished name='#setDefaults' timestamp='2016-05-25T10:38:41.704']
##teamcity[testSuiteStarted name='#setUrlParams' timestamp='2016-05-25T10:38:41.704']
##teamcity[testStarted name='sets up hash' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.704']
##teamcity[testFinished name='sets up hash' timestamp='2016-05-25T10:38:41.706']
##teamcity[testStarted name='sets up catalog' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.707']
##teamcity[testFinished name='sets up catalog' timestamp='2016-05-25T10:38:41.707']
##teamcity[testSuiteFinished name='#setUrlParams' timestamp='2016-05-25T10:38:41.708']
##teamcity[testSuiteFinished name='Config' timestamp='2016-05-25T10:38:41.708']
##teamcity[progressFinish 'Running Jasmine Tests']
 PASS  __tests__/Config-test.js (0.738s)
Running 1 test suite...##teamcity[progressStart 'Running Jasmine Tests']
##teamcity[testSuiteStarted name='UrlParamsIterator' timestamp='2016-05-25T10:38:41.839']
##teamcity[testSuiteStarted name='#constructor' timestamp='2016-05-25T10:38:41.840']
##teamcity[testStarted name='inherits the Iterator class' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.841']
##teamcity[testFinished name='inherits the Iterator class' timestamp='2016-05-25T10:38:41.844']
##teamcity[testStarted name='splits the Url params and adds it to the list' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.844']
##teamcity[testFinished name='splits the Url params and adds it to the list' timestamp='2016-05-25T10:38:41.845']
##teamcity[testStarted name='understands Url string' captureStandardOutput='true' timestamp='2016-05-25T10:38:41.845']
##teamcity[testFinished name='understands Url string' timestamp='2016-05-25T10:38:41.847']
##teamcity[testSuiteFinished name='#constructor' timestamp='2016-05-25T10:38:41.848']
##teamcity[testSuiteFinished name='UrlParamsIterator' timestamp='2016-05-25T10:38:41.848']
##teamcity[progressFinish 'Running Jasmine Tests']
 PASS  __tests__/UrlParamsIterator-test.js (0.093s)
23 tests passed (23 total in 4 test suites, run time 3.007s)
----------------------------|----------|----------|----------|----------|----------------|
File                        |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
----------------------------|----------|----------|----------|----------|----------------|
 blablabla/                 |      100 |      100 |      100 |      100 |                |
  env-setup.js              |      100 |      100 |      100 |      100 |                |
 blablabla/src/             |    86.67 |    68.18 |    78.57 |    90.32 |                |
  Config.js                 |    77.14 |       50 |    66.67 |    78.26 | 31,32,33,35,58 |
  Iterator.js               |    93.75 |     87.5 |     87.5 |    95.24 |             30 |
  Promise.js                |    86.89 |    72.22 |       75 |    91.67 |      95,97,107 |
  UrlParamsIterator.js      |    89.19 |    58.33 |      100 |      100 |                |
 blablabla/src/__mocks__/   |      100 |      100 |      100 |      100 |                |
  Env.js                    |      100 |      100 |      100 |      100 |                |
----------------------------|----------|----------|----------|----------|----------------|
All files                   |    87.06 |    68.18 |    78.57 |    90.82 |                |
----------------------------|----------|----------|----------|----------|----------------|

I will join this one since I have the same issue with manual mocks. Something has to be done about this coverage.

Well at least you know your mocks are being used

@StephanBijzitter problem is, huge mocks are partially covered ---> this harms overall coverage
And this results in failed thresholds. Finally, CI build fails. Not so good.

I don't mind write special tests for mocks coverage 😆

@ColCh would you like to send a PR? The check for mocks needs to be added here: https://github.com/facebook/jest/blob/101cda7511109408891e6f87773f61a2d008e213/packages/jest-cli/src/Runtime/Runtime.js#L234 the config field is mocksPattern.

@cpojer failing test case + one line. hm, I will give a try tomorrow

@cpojer it looks like that doesn't filter any configuration files and mocks before. It may solve the problem if you refactor _collectCoverageOnlyFrom_ to accept regular expressions. Actually the way how it's implemented seems to be incorrect.

The code below gathers coverage only from _src/app.js_ file

{
   "collectCoverageOnlyFrom": {
      "src/app.js": false
   }
}

@ColCh we already have an integration test for coverage. You could add a manual mock there, load it in the test and make sure it isn't part of the coverage output.

@mateuszsokola yeah, we should completely change collectCoverageOnlyFrom, I agree. I think we should also only turn on coverage after we run the setup files, need to think about this a bit :)

Thanks @ColCh! This will be fixed in the next release.

In case someone came here looking for this, Jest has a coveragePathIgnorePatterns option

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hramos picture hramos  Â·  3Comments

jardakotesovec picture jardakotesovec  Â·  3Comments

mmcgahan picture mmcgahan  Â·  3Comments

ticky picture ticky  Â·  3Comments

GrigoryPtashko picture GrigoryPtashko  Â·  3Comments