10

I'm running tests in multiple projects of my nx angular monorepo and would like to get a single code coverage report of all projects with all code files covert from the tests. The test-runs seems to scope the analysed code to the current nx project and I do not get the coverage report from a base library (used from multiple projects). This might not be best practise, but I would like to analyse, which code is in use und which can be refactored / removed.

I have already tried some solution strategies, but none of them has resolved all my problems.

I have extended the jest.config.js of all my projects and add the coverage and test reporters (currently junit & cobertura for publish/display in Azure DevOps)

jest.config.js


module.exports = {
    ...
    coverageReporters: ["cobertura", "html"], 
    ...
    reporters: [
        "default",
        ["jest-junit", { outputDirectory: "coverage/libs/my-lib", outputName: "junit.xml" }]
    ],
    collectCoverageFrom: [
        "**/*.{ts,tsx}",
        "!**/node_modules/**",
        "!**/coverage/**",
        "!**/vendor/**"
    ]
};

run all projects

I tried to run all tests in every app and library with the nx run-many command.

nx run-many --all --target=test --parallel  -- --collectCoverage --coverage

I get a coverage folder for each with each test/coverage report and might be able to merge them to a single report (e.g. https://stackoverflow.com/a/58649061/1374945). But there were not all source files included and coverage runs was always scoped to one single project (usage of library code from multiple apps was not recorded).

run global jest config

The secound aproach was to run the global jest config directly throw jest.

node \"node_modules/jest/bin/jest.js\" -c \"jest.config.js\" --coverage --collectCoverage  --coverageReporters=html --verbose=false

I think, this might be similar to the first approach, because jest also has the project configuration an run each project independently. I get one coverage and test report with all results in it. But there were also not all source files included and coverage runs was always scoped to one single project (usage of library code from multiple apps was not recorded).

module.exports = {
    projects: getJestProjects(),
    reporters: [
        "default",
        ["jest-junit", { outputDirectory: "coverage", outputName: "junit.xml" }],
        ["./node_modules/jest-html-reporter", {
            "pageTitle": "Test Report",
            "outputPath": "coverage/test-report.html",
            "includeConsoleLog": true,
            "includeFailureMsg": true,
            "includeSuiteFailure": true
        }]
    ],
    collectCoverageFrom: [
        "**/*.{ts,tsx}",
        "!**/node_modules/**",
        "!**/coverage/**",
        "!**/vendor/**"
    ]
};

Libraries

  • angular 13
  • jest 27
Richard Liebmann
  • 416
  • 1
  • 6
  • 19

2 Answers2

1

Well, for my use case, it was a very simple hack -- and yes, I've been searching for quite some hours before I came up with this. In the jest.config.ts of our primary (frontend) app, I've added the following to the default properties:

  projects: getJestProjects().map(
    (val: unknown) => (val as string).replace('<rootDir>', '<rootDir>/../../')
  ),

as well as the corresponding import at the top:

import { getJestProjects } from '@nrwl/jest';

Now, whenever I run nx run frontend:test, it runs all of the tests from (I think) workspace.json's projects. Which is great, because we only have the app.component inside the app -- everything else is in the libs folder. Adding --codeCoverage to this run works just fine.

All the components in the libs folder that frontend depends on, are actually in libs/frontend -- so once another app comes into this monorepo, I will filter in only the projects with {app,lib}/frontend/ or something.

Adam
  • 63
  • 5
  • Did you add the `jest.config.ts` file in root folder? – kittu Nov 01 '22 at 11:00
  • What is `('', '/../../')` – kittu Nov 01 '22 at 11:13
  • No, I didn't add it to the `jest.config.ts` in the root folder, because I wanted to execute all tests only if my 'apps/frontend' is tested. That's why I needed the `('', '/../../')` part: go two directories up from the folder 'apps/frontend' because `getJestProjects()` returns directories based on the top-level folder. Also, the `../../` has to be after `` as it seems that the expansion further down the line only happens if this tag is at the beginning. – Adam Nov 03 '22 at 09:41
1

If you can use the cobertura reporting format, you can use the cobertura-merge library to create a single test coverage report that merges results from each project's individual test coverage report into one for the whole monorepo.

First run your tests with coverage reporting for all projects, then run cobertura-merge to merge the resulting reports into one report.

Detailed step-by-step instructions are here: https://medium.com/hi-health-tech-blog/add-aggregated-test-coverage-to-gitlab-pipelines-with-an-nx-monorepo-cf91bc0360f7