Skip to content

Commit ac53a9f

Browse files
avivkellerlouwers
authored andcommitted
test_runner: report coverage thresholds in test:coverage
PR-URL: nodejs#54813 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent a716455 commit ac53a9f

File tree

4 files changed

+61
-15
lines changed

4 files changed

+61
-15
lines changed

doc/api/test.md

+5
Original file line numberDiff line numberDiff line change
@@ -2814,6 +2814,11 @@ are defined, while others are emitted in the order that the tests execute.
28142814
numbers and the number of times they were covered.
28152815
* `line` {number} The line number.
28162816
* `count` {number} The number of times the line was covered.
2817+
* `thresholds` {Object} An object containing whether or not the coverage for
2818+
each coverage type.
2819+
* `function` {number} The function coverage threshold.
2820+
* `branch` {number} The branch coverage threshold.
2821+
* `line` {number} The line coverage threshold.
28172822
* `totals` {Object} An object containing a summary of coverage for all
28182823
files.
28192824
* `totalLineCount` {number} The total number of lines.

lib/internal/test_runner/coverage.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ class CoverageLine {
5151
}
5252

5353
class TestCoverage {
54-
constructor(coverageDirectory, originalCoverageDirectory, workingDirectory, excludeGlobs, includeGlobs) {
54+
constructor(coverageDirectory, originalCoverageDirectory, workingDirectory, excludeGlobs, includeGlobs, thresholds) {
5555
this.coverageDirectory = coverageDirectory;
5656
this.originalCoverageDirectory = originalCoverageDirectory;
5757
this.workingDirectory = workingDirectory;
5858
this.excludeGlobs = excludeGlobs;
5959
this.includeGlobs = includeGlobs;
60+
this.thresholds = thresholds;
6061
}
6162

6263
#sourceLines = new SafeMap();
@@ -143,6 +144,7 @@ class TestCoverage {
143144
coveredBranchPercent: 0,
144145
coveredFunctionPercent: 0,
145146
},
147+
thresholds: this.thresholds,
146148
};
147149

148150
if (!coverage) {
@@ -505,6 +507,12 @@ function setupCoverage(options) {
505507
cwd,
506508
options.coverageExcludeGlobs,
507509
options.coverageIncludeGlobs,
510+
{
511+
__proto__: null,
512+
line: options.lineCoverage,
513+
branch: options.branchCoverage,
514+
function: options.functionCoverage,
515+
},
508516
);
509517
}
510518

lib/internal/test_runner/test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1043,8 +1043,6 @@ class Test extends AsyncResource {
10431043
reporter.diagnostic(nesting, loc, `duration_ms ${this.duration()}`);
10441044

10451045
if (coverage) {
1046-
reporter.coverage(nesting, loc, coverage);
1047-
10481046
const coverages = [
10491047
{ __proto__: null, actual: coverage.totals.coveredLinePercent,
10501048
threshold: this.config.lineCoverage, name: 'line' },
@@ -1063,6 +1061,8 @@ class Test extends AsyncResource {
10631061
reporter.diagnostic(nesting, loc, `Error: ${NumberPrototypeToFixed(actual, 2)}% ${name} coverage does not meet threshold of ${threshold}%.`);
10641062
}
10651063
}
1064+
1065+
reporter.coverage(nesting, loc, coverage);
10661066
}
10671067

10681068
if (harness.watching) {

test/parallel/test-runner-coverage-thresholds.js

+45-12
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@ function getTapCoverageFixtureReport() {
4444
}
4545

4646
const fixture = fixtures.path('test-runner', 'coverage.js');
47-
const neededArguments = [
48-
'--experimental-test-coverage',
49-
'--test-reporter', 'tap',
50-
];
47+
const reporter = fixtures.fileURL('test-runner/custom_reporters/coverage.mjs');
5148

5249
const coverages = [
5350
{ flag: '--test-coverage-lines', name: 'line', actual: 78.35 },
@@ -56,10 +53,12 @@ const coverages = [
5653
];
5754

5855
for (const coverage of coverages) {
59-
test(`test passing ${coverage.flag}`, async (t) => {
56+
test(`test passing ${coverage.flag}`, () => {
6057
const result = spawnSync(process.execPath, [
61-
...neededArguments,
58+
'--test',
59+
'--experimental-test-coverage',
6260
`${coverage.flag}=25`,
61+
'--test-reporter', 'tap',
6362
fixture,
6463
]);
6564

@@ -70,10 +69,27 @@ for (const coverage of coverages) {
7069
assert(!findCoverageFileForPid(result.pid));
7170
});
7271

73-
test(`test failing ${coverage.flag}`, async (t) => {
72+
test(`test passing ${coverage.flag} with custom reporter`, () => {
73+
const result = spawnSync(process.execPath, [
74+
'--test',
75+
'--experimental-test-coverage',
76+
`${coverage.flag}=25`,
77+
'--test-reporter', reporter,
78+
fixture,
79+
]);
80+
81+
const stdout = JSON.parse(result.stdout.toString());
82+
assert.strictEqual(stdout.summary.thresholds[coverage.name], 25);
83+
assert.strictEqual(result.status, 0);
84+
assert(!findCoverageFileForPid(result.pid));
85+
});
86+
87+
test(`test failing ${coverage.flag}`, () => {
7488
const result = spawnSync(process.execPath, [
75-
...neededArguments,
89+
'--test',
90+
'--experimental-test-coverage',
7691
`${coverage.flag}=99`,
92+
'--test-reporter', 'tap',
7793
fixture,
7894
]);
7995

@@ -84,9 +100,25 @@ for (const coverage of coverages) {
84100
assert(!findCoverageFileForPid(result.pid));
85101
});
86102

87-
test(`test out-of-range ${coverage.flag} (too high)`, async (t) => {
103+
test(`test failing ${coverage.flag} with custom reporter`, () => {
104+
const result = spawnSync(process.execPath, [
105+
'--test',
106+
'--experimental-test-coverage',
107+
`${coverage.flag}=99`,
108+
'--test-reporter', reporter,
109+
fixture,
110+
]);
111+
112+
const stdout = JSON.parse(result.stdout.toString());
113+
assert.strictEqual(stdout.summary.thresholds[coverage.name], 99);
114+
assert.strictEqual(result.status, 1);
115+
assert(!findCoverageFileForPid(result.pid));
116+
});
117+
118+
test(`test out-of-range ${coverage.flag} (too high)`, () => {
88119
const result = spawnSync(process.execPath, [
89-
...neededArguments,
120+
'--test',
121+
'--experimental-test-coverage',
90122
`${coverage.flag}=101`,
91123
fixture,
92124
]);
@@ -96,9 +128,10 @@ for (const coverage of coverages) {
96128
assert(!findCoverageFileForPid(result.pid));
97129
});
98130

99-
test(`test out-of-range ${coverage.flag} (too low)`, async (t) => {
131+
test(`test out-of-range ${coverage.flag} (too low)`, () => {
100132
const result = spawnSync(process.execPath, [
101-
...neededArguments,
133+
'--test',
134+
'--experimental-test-coverage',
102135
`${coverage.flag}=-1`,
103136
fixture,
104137
]);

0 commit comments

Comments
 (0)