Search code examples
javascriptjestjsbabeljscode-coverage

Why is my Jest code coverage report invalid?


When I generate a Jest code coverage report for my Vue 2.7.X app, the lines shown as covered/uncovered in the report don't make any sense:

enter image description here

The red sections in this report should indicate code that's not covered (executed) by the test suite, but obviously it makes no sense to show comments (lines 290, 291) as uncovered, or to show (part of) line 298 as uncovered when the lines before and after are covered.

I guess what's happening is that the lines which Jest detects as uncovered are not being correctly mapped back to the source code, so there may be a problem with the Babel transpilation.

I generate the code coverage report with yarn jest --coverage and the application source code is written in JavaScript (rather than TypeScript).

some of the dependencies from package.json which may be relevant to the problem are shown below:

  "devDependencies": {
    "@babel/core": "^7.20.5",
    "@babel/preset-env": "^7.20.2",
    "@vue/test-utils": "1.3.3",
    "@vue/vue2-jest": "29.2.2",
    "@vitejs/plugin-vue2": "^2.2.0",
    "babel-jest": "^29.3.1",
    "http-proxy": "^1.18.1",
    "jest": "^29.3.1",
    "jest-environment-jsdom": "^29.3.1",
    "sass": "1.32.13",
    "sass-lint": "^1.13.1",
    "start-server-and-test": "^1.14.0",
    "unplugin-vue-components": "^0.22.12",
    "vite": "^4.0.1",
    "vite-plugin-rewrite-all": "^1.0.1",
    "vue-template-compiler": "^2.7.14"
  }

Minimum Reproducible Example

I've created a minimal Git repo that demonstrates the problem.

  1. Clone the repo
  2. Run yarn install && yarn test:unit:coverage to generate the coverage report (or use npm instead)
  3. Open the file coverage/lcov-report/index.html to see the report

If you open the page for components/toaster-message.vue, it says 1/2 branches and 2/3 functions are covered, but none of the lines are marked in red (hideAppMessage should be red because it's not tested).

If you open the page for views/login.vue the lines that are marked in red (uncovered) don't make any sense. There are no tests for this component.


Solution

  • What worked for me was adding coverageProvider: 'v8' to the jest.config.js. I'm not entirely sure why changing coverageProvider works, but seems like vue-jest is having general problems with collecting coverage correctly due to babel dependency changes.

    Try adding this to your Jest configuration:

    coverageProvider: 'v8'
    

    Then npm run test:unit:coverage.

    This worked on Node v16.16.0 and v18.12.1.