ThisCalculator

Everyday

Angular Code Coverage Reports: Generate & Configure

Updated · Standard formula, shown below

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

  1. Run tests with coverage
    The simplest way to generate a coverage report is to run the Angular CLI test command with the --code-coverage flag:
    ng test --code-coverage
    This runs your unit tests once (not in watch mode) and creates a coverage/ folder in the project root containing an HTML report you can open in a browser.
  2. Open the HTML report
    After the command finishes, navigate to coverage/ in your project folder. Open index.html in 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).
  3. Make coverage the default
    To avoid typing the flag every time, edit angular.json. Find the test target for your project (usually under projects.<project-name>.architect.test). Add "codeCoverage": true to the options object:

    "test": {
      "builder": "@angular-devkit/build-angular:karma",
      "options": {
        "codeCoverage": true,
        "karmaConfig": "karma.conf.js"
      }
    }

    Now ng test will always generate coverage.

  4. Set coverage thresholds
    To enforce minimum coverage percentages, add a coverageThreshold object in the same options block. 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".

  5. Change the coverage report format
    By default, Angular uses the lcov and text-summary reporters. To customize, edit karma.conf.js. Look for the coverageIstanbulReporter section. You can change the reports array to include formats like html, lcovonly, text, json, or clover. Example:

    coverageIstanbulReporter: {
      dir: require('path').join(__dirname, './coverage'),
      reports: ['html', 'lcovonly', 'text-summary'],
      fixWebpackSourcePaths: true
    }
  6. Exclude files from coverage
    Some files (e.g., main.ts, polyfills.ts, or generated modules) shouldn’t be counted. In karma.conf.js, inside the coverageIstanbulReporter object, add a "skipFilesWithNoCoverage" property or use exclude patterns. For example:

    coverageIstanbulReporter: {
      ...
      "skipFilesWithNoCoverage": true,
      "exclude": ["**/*.spec.ts", "**/main.ts"]
    }

    Note: spec files are usually already excluded by default.

  7. Run in CI (Continuous Integration)
    For CI pipelines, use the --watch=false flag and set the browser to a headless one. Example command:
    ng test --code-coverage --watch=false --browsers=ChromeHeadless
    The generated coverage/lcov.info file can be uploaded to services like Coveralls or Codecov for tracking.
  8. View coverage in IDE
    Some IDEs (like VS Code) can display coverage directly. Install a coverage extension and point it to the coverage/lcov.info file. This lets you see red/green highlights in your source files while editing.

Common Mistakes

  • Forgetting the watch flag: Running ng test --code-coverage without --watch=false will 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.test section. 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 lcovonly reporter. It generates lcov.info which is widely supported.
  • Combine with watch mode for development: You can run ng test --code-coverage --watch=true to 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-coverage or set codeCoverage: true in 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: true is set in the coverageIstanbulReporter in karma.conf.js.
  • Thresholds not working: Verify that you placed coverageThreshold inside the options object 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=ChromeHeadless and get an error, install puppeteer or use the ChromeHeadlessNoSandbox custom launcher in CI environments. You can add a custom launcher in karma.conf.js.
  • Coverage report includes node_modules: Add an exclude pattern in the coverageIstanbulReporter to skip **/node_modules/** if it’s not already excluded.

Frequently Asked Questions

  1. 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.
  2. 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.
  3. How do I exclude a specific file from coverage?
    In karma.conf.js, inside coverageIstanbulReporter, add an exclude array with glob patterns. For example: exclude: ['**/environment.prod.ts'].
  4. 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.
  5. 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.
  6. Can I set per-file coverage thresholds?
    Yes, in the coverageThreshold object, 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.