@nrwl/nx angular Run all test for coverage in a single test run to get all covered code in my mono repo
Asked Answered
S

2

13

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://mcmap.net/q/437700/-is-there-anyway-to-merge-cobertura-coverage-xml-reports-together). 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
Secateurs answered 26/3, 2022 at 12:26 Comment(1)
Great question, I am stumped at the same problem. See github.com/nrwl/nx/issues/3437Lavina
K
2

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

Knotweed answered 2/3, 2023 at 10:16 Comment(0)
C
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.

Cervicitis answered 12/8, 2022 at 13:27 Comment(3)
Did you add the jest.config.ts file in root folder?Rh
What is ('<rootDir>', '<rootDir>/../../')Rh
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 ('<rootDir>', '<rootDir>/../../') 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 <rootDir> as it seems that the expansion further down the line only happens if this tag is at the beginning.Cervicitis

© 2022 - 2024 — McMap. All rights reserved.