Skip to content

fix(jest): scope coverage output per-project in multi-project workspaces (fixes #1009)#2212

Open
just-jeb wants to merge 3 commits into
masterfrom
fix/1009-coverage-namespacing
Open

fix(jest): scope coverage output per-project in multi-project workspaces (fixes #1009)#2212
just-jeb wants to merge 3 commits into
masterfrom
fix/1009-coverage-namespacing

Conversation

@just-jeb
Copy link
Copy Markdown
Owner

@just-jeb just-jeb commented May 7, 2026

PR Checklist

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

[x] Bugfix
[ ] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

In multi-project workspaces, all projects write Jest coverage output to the same workspace-root coverage/ directory. When projects run in sequence (ng test project-a --coverage; ng test project-b --coverage), the second run overwrites the first. There is no way to get coverage for multiple projects simultaneously.

Issue Number: #1009

What is the new behavior?

coverageDirectory is set unconditionally in the per-project default config to <projectRoot>/coverage. For a standard ng new single-project workspace, projectRoot === workspaceRoot, so output stays at ./coverage — no change. For multi-project workspaces, each project writes to its own projects/<name>/coverage directory.

Users can still override via their own jest.config.ts (the per-project user layer is merged last).

Does this PR introduce a breaking change?

[ ] Yes
[x] No

Standard single-project workspaces (ng new) are unaffected. Multi-project workspaces previously had broken behavior (overwriting). The only behavior change for users is the library-only workspace where projectRoot is not the workspace root — those will see coverage at <projectRoot>/coverage instead of ./coverage. Will be called out in CHANGELOG.

Other information

N/A

@just-jeb just-jeb added bug Something isn't working builders:jest labels May 11, 2026
@just-jeb just-jeb force-pushed the fix/1009-coverage-namespacing branch 7 times, most recently from 1194137 to 21eccdd Compare May 15, 2026 04:30
@just-jeb
Copy link
Copy Markdown
Owner Author

Potentially breaking?

@just-jeb just-jeb force-pushed the fix/1009-coverage-namespacing branch from 21eccdd to 426d01c Compare May 15, 2026 12:31
Houston and others added 2 commits May 16, 2026 16:30
…isions (#1009)

When running ng test in a multi-project Angular workspace, each project's coverage
output was written to the same directory (e.g. root ./coverage/), causing each
successive run to overwrite the previous project's coverage report.

Fix: set coverageDirectory in DefaultConfigResolver.resolveForProject() to
<projectRoot>/coverage so each Angular project's coverage lands in its own
isolated output directory.

This is a project-level default that can still be overridden per-project via
the jest.config.js customization mechanism.

Also removes erroneous debug console.log statements from jest-configuration-builder.ts
and fixes the scopeOutputDirectoriesForProjects approach, which incorrectly mutated
the Jest 'projects' array (breaking --find-related-tests and project path resolution).

Adds: unit test for coverageDirectory scoping, integration test validate-coverage.js
@just-jeb just-jeb force-pushed the fix/1009-coverage-namespacing branch from 426d01c to 4f6f462 Compare May 16, 2026 16:30
@just-jeb
Copy link
Copy Markdown
Owner Author

Re: 'Potentially breaking?'

Yes — it changes coverage output from <workspace-root>/coverage/ to <project-root>/coverage/ per project. Intentional fix for the overwrite collision in multi-project workspaces, but it will break CI pipelines reading coverage from a hardcoded ./coverage/ path.

Already labeled breaking-change — waiting for the batch-breaking-changes merge decision.

…l integration test

The unit test asserting config.coverageDirectory field value is an
implementation detail check. The behavioral proof — that coverage
files actually land under projects/<name>/coverage/ on disk — is
covered by the integration test in validate-coverage.js. Remove the
unit test to avoid false confidence from a config-shape assertion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working builders:jest

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant