Skip to main content

Test Coverage with Jest's Built in Coverage

Introduction​

Code coverage shows how much of your code is tested. Jest's built in coverage can easily be used to show code coverage reports.


Concepts​

Coverage reports show:

  • Statements covered.
  • Branches (if/else) covered.
  • Functions covered.
  • Lines covered.

Helps identify untested parts of your code.


Examples​

Running Coverage with Jest​

Jest includes built-in coverage reporting, so no additional packages are required.

Run coverage directly from the command line:

npx jest --coverage

Or add a script to your package.json:

"scripts": {
"test": "jest",
"coverage": "jest --coverage"
},

Running coverage will output a report showing:

  • Statements : 80% ( 8/10 )
  • Branches : 75% ( 3/4 )
  • Functions : 100% ( 2/2 )
  • Lines : 80% ( 8/10 )

Challenges​

1. Run jest coverage​

  • Run jest coverage on your project and check coverage.
💡 Show Answer
npm run coverage

2. Improve coverage by adding tests​

  • Add tests until coverage improves, then rerun.
💡 Show Answer
// add missing branch test to increase coverage

3. grade function test​

  • Write a function with an if/else branch.
  • See how coverage reports branch testing.
💡 Show Answer
// testCode.js
function checkNumber(num) {
if (num > 0) {
return "Positive";
} else if (num < 0) {
return "Negative";
} else {
return "Zero";
}
}

module.exports = { checkNumber };

// testCode.test.js
const { checkNumber } = require("./testCode");

test("checkNumber returns 'Positive' for positive numbers", () => {
expect(checkNumber(5)).toBe("Positive");
});

test("checkNumber returns 'Negative' for negative numbers", () => {
expect(checkNumber(-3)).toBe("Negative");
});

test("checkNumber returns 'Zero' for zero", () => {
expect(checkNumber(0)).toBe("Zero");
});

4. Unused code uncovered​

  • Write a function with unused code and observe how coverage reports it.
💡 Show Answer
function unused(){
return "never tested";
}
// shows up as uncovered in report

5. HTML report​

  • Configure Jest to output an HTML report and open it in a browser.
💡 Show Answer
// Add a jest config file jest.config.js
module.exports = {
collectCoverage: false, // We'll enable this via command line
coverageDirectory: 'coverage',
coverageReporters: [
'text',
'html',
'lcov'
],
collectCoverageFrom: [
'**/*.js',
'!**/*.test.js',
'!**/*.spec.js',
'!**/node_modules/**',
'!**/coverage/**',
'!jest.config.js'
],
testEnvironment: 'node'
};

6. Coverage thresholds​

  • Add coverage thresholds in jest.config.js to fail below 80%.
💡 Show Answer
// Update jest.config.js
module.exports = {
collectCoverage: false, // We'll enable this via command line
coverageDirectory: "coverage",
coverageReporters: ["text", "html", "lcov"],
collectCoverageFrom: [
"**/*.js",
"!**/*.test.js",
"!**/*.spec.js",
"!**/node_modules/**",
"!**/coverage/**",
"!jest.config.js",
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
testEnvironment: "node",
};

7. Exclude files​

  • Exclude the test file from coverage with and see the effect.
💡 Show Answer
// Update jest.config.js to include
collectCoverageFrom: [
"**/*.js",
"!**/*.test.js",
"!**/*.spec.js",
"!**/node_modules/**",
"!**/coverage/**",
"!jest.config.js",
// Additional exclusion examples:
// "!**/dist/**", // Exclude build/dist directories
// "!**/build/**", // Exclude build directories
// "!**/*.config.js", // Exclude all config files
// "!**/scripts/**", // Exclude scripts directory
// "!**/docs/**", // Exclude documentation
// "!**/examples/**", // Exclude example files
// "!**/migrations/**", // Exclude database migrations
// "!**/seeds/**", // Exclude database seeds
// "!index.js", // Exclude specific files
],

8. Untested error handling​

  • Show how untested error handling paths reduce coverage.
💡 Show Answer
function safeDivide(a, b) {
if (b === 0) throw new Error();
return a / b;
}

module.exports = { safeDivide };

9. Incremental coverage​

  • Add a test at a time to see how coverage changes (any project)
💡 Show Answer
// add one test at a time and rerun coverage to see % increase

10. Async coverage​

💡 Show Answer
// testCode.js
async function fetch(flag) {
if (flag) return "ok";
else throw "fail";
}

module.exports = { fetch };

// testCode.test.js
const { fetch } = require("./testCode");

test("ok", async () => {
expect(await fetch(true)).toBe("ok");
});
test("fail", async () => {
await expect(fetch(false)).rejects.toBe("fail");
});