Angular Code Coverage Reports: Generate & Configure
This guide shows you how to generate and configure code coverage reports for Angular applications using the built-in Karma test runner and Istanbul coverage tool. You’ll learn how to run tests with coverage, customize the report format, set coverage thresholds, and integrate coverage into your development workflow. By the end, you’ll be able to see exactly which lines, branches, functions, and statements your tests cover.
What You’ll Need
- An existing Angular project (created with Angular CLI, version 8 or later)
- Node.js and npm installed
- Basic familiarity with running Angular tests (ng test)
Step-by-Step
- Run tests with coverage
The simplest way to generate a coverage report is to run the Angular CLI test command with the--code-coverageflag:
ng test --code-coverage
This runs your unit tests once (not in watch mode) and creates acoverage/folder in the project root containing an HTML report you can open in a browser. - Open the HTML report
After the command finishes, navigate tocoverage/in your project folder. Openindex.htmlin a browser. You’ll see a table listing each source file with percentages for Statements, Branches, Functions, and Lines. Click any file to see line-by-line highlighting: green for covered, red for uncovered, yellow for partial (e.g., a branch where only one path is tested). - Make coverage the default
To avoid typing the flag every time, editangular.json. Find thetesttarget for your project (usually underprojects.<project-name>.architect.test). Add"codeCoverage": trueto theoptionsobject:"test": { "builder": "@angular-devkit/build-angular:karma", "options": { "codeCoverage": true, "karmaConfig": "karma.conf.js" } }Now
ng testwill always generate coverage. - Set coverage thresholds
To enforce minimum coverage percentages, add acoverageThresholdobject in the sameoptionsblock. For example:"codeCoverage": true, "coverageThreshold": { "global": { "statements": 80, "branches": 75, "functions": 80, "lines": 80 } }If any global percentage falls below the threshold, the test run fails. You can also set per-file thresholds using
"each"instead of"global". - Change the coverage report format
By default, Angular uses thelcovandtext-summaryreporters. To customize, editkarma.conf.js. Look for thecoverageIstanbulReportersection. You can change thereportsarray to include formats likehtml,lcovonly,text,json, orclover. Example:coverageIstanbulReporter: { dir: require('path').join(__dirname, './coverage'), reports: ['html', 'lcovonly', 'text-summary'], fixWebpackSourcePaths: true } - Exclude files from coverage
Some files (e.g., main.ts, polyfills.ts, or generated modules) shouldn’t be counted. Inkarma.conf.js, inside thecoverageIstanbulReporterobject, add a"skipFilesWithNoCoverage"property or useexcludepatterns. For example:coverageIstanbulReporter: { ... "skipFilesWithNoCoverage": true, "exclude": ["**/*.spec.ts", "**/main.ts"] }Note: spec files are usually already excluded by default.
- Run in CI (Continuous Integration)
For CI pipelines, use the--watch=falseflag and set the browser to a headless one. Example command:
ng test --code-coverage --watch=false --browsers=ChromeHeadless
The generatedcoverage/lcov.infofile can be uploaded to services like Coveralls or Codecov for tracking. - View coverage in IDE
Some IDEs (like VS Code) can display coverage directly. Install a coverage extension and point it to thecoverage/lcov.infofile. This lets you see red/green highlights in your source files while editing.
Common Mistakes
- Forgetting the watch flag: Running
ng test --code-coveragewithout--watch=falsewill keep the process alive and not generate a report until you stop it. In CI, always use--watch=false. - Editing the wrong angular.json project: If you have multiple projects, ensure you’re editing the correct
architect.testsection. Changes to one project don’t affect others. - Thresholds too strict: Setting thresholds to 100% on a new project will cause immediate failures. Start with lower values and increase gradually.
- Not excluding spec files: If your spec files appear in the coverage report, they are inflating your numbers because they contain test code. The default configuration usually excludes them, but if you override the exclude list, you might break that.
- Ignoring branch coverage: Line coverage alone can be misleading. A line might be executed but not all its branches (e.g., both if/else paths) are tested. Pay attention to branch percentages.
Tips
- Use the text-summary reporter: Add
'text-summary'to the reports array in karma.conf.js. It prints a quick summary to the terminal, so you don’t have to open the HTML report every time. - Focus on critical files: Don’t try to cover every line of code. Prioritize business logic, services, and components with complex conditionals. Boilerplate like module declarations often don’t need testing.
- Run coverage regularly: Make it part of your pre-commit hook or CI pipeline. This prevents coverage from silently dropping.
- Use the lcov format for external tools: If you want to integrate with code coverage services, keep the
lcovonlyreporter. It generateslcov.infowhich is widely supported. - Combine with watch mode for development: You can run
ng test --code-coverage --watch=trueto see coverage update as you write tests, though it may slow down the test runner.
Troubleshooting
- No coverage folder generated: Make sure you used
--code-coverageor setcodeCoverage: truein angular.json. Also check that the test run completed without errors. If using watch mode, stop it (Ctrl+C) to generate the report. - Coverage percentages are 0%: This usually happens when the coverage reporter can’t map the compiled code back to TypeScript source. Ensure
fixWebpackSourcePaths: trueis set in thecoverageIstanbulReporterin karma.conf.js. - Thresholds not working: Verify that you placed
coverageThresholdinside theoptionsobject of the test target in angular.json. Also, check that you’re not using an older Angular version where thresholds are configured differently (in karma.conf.js). - Tests fail with “Coverage threshold not met”: This is expected if your coverage is below the threshold. Either improve your tests or temporarily lower the threshold to get the suite green, then work on increasing coverage.
- Headless Chrome not found: If you use
--browsers=ChromeHeadlessand get an error, install puppeteer or use theChromeHeadlessNoSandboxcustom launcher in CI environments. You can add a custom launcher in karma.conf.js. - Coverage report includes node_modules: Add an
excludepattern in the coverageIstanbulReporter to skip**/node_modules/**if it’s not already excluded.
Frequently Asked Questions
- What is the difference between line and branch coverage?
Line coverage measures whether a line of code was executed. Branch coverage measures whether each possible path (e.g., if/else, switch cases) was taken. Branch coverage is stricter because a line can be executed but only one branch tested. - Can I generate coverage without running tests?
No, coverage is collected during test execution. You must run the test suite at least once to produce a report. - How do I exclude a specific file from coverage?
In karma.conf.js, insidecoverageIstanbulReporter, add anexcludearray with glob patterns. For example:exclude: ['**/environment.prod.ts']. - What is the lcov.info file used for?
It’s a machine-readable coverage report used by services like Coveralls, Codecov, or SonarQube to track coverage over time and display badges. - Why do my coverage numbers differ between local and CI?
Differences can occur due to browser versions, test order, or configuration differences (e.g., headless vs. headed). Ensure you use the same Angular CLI version and karma config in both environments. - Can I set per-file coverage thresholds?
Yes, in thecoverageThresholdobject, use"each"instead of"global". This enforces the minimum for every file individually.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.