GeezerVison is showing github.com — test_runner: report coverage thresholds in `test:coverage` · nodejs/node@a52c199
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/test.md +5Lines changed: 5 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -2806,6 +2806,11 @@ are defined, while others are emitted in the order that the tests execute. | 2806 | 2806 | numbers and the number of times they were covered. | 2807 | 2807 | * `line` {number} The line number. | 2808 | 2808 | * `count` {number} The number of times the line was covered. | | 2809 | + * `thresholds` {Object} An object containing whether or not the coverage for | | 2810 | + each coverage type. | | 2811 | + * `function` {number} The function coverage threshold. | | 2812 | + * `branch` {number} The branch coverage threshold. | | 2813 | + * `line` {number} The line coverage threshold. | 2809 | 2814 | * `totals` {Object} An object containing a summary of coverage for all | 2810 | 2815 | files. | 2811 | 2816 | * `totalLineCount` {number} The total number of lines. | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/test_runner/coverage.js +9-1Lines changed: 9 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -51,12 +51,13 @@ class CoverageLine { | 51 | 51 | } | 52 | 52 |
| 53 | 53 | class TestCoverage { | 54 | | - constructor(coverageDirectory, originalCoverageDirectory, workingDirectory, excludeGlobs, includeGlobs) { | | 54 | + constructor(coverageDirectory, originalCoverageDirectory, workingDirectory, excludeGlobs, includeGlobs, thresholds) { | 55 | 55 | this.coverageDirectory = coverageDirectory; | 56 | 56 | this.originalCoverageDirectory = originalCoverageDirectory; | 57 | 57 | this.workingDirectory = workingDirectory; | 58 | 58 | this.excludeGlobs = excludeGlobs; | 59 | 59 | this.includeGlobs = includeGlobs; | | 60 | + this.thresholds = thresholds; | 60 | 61 | } | 61 | 62 |
| 62 | 63 | #sourceLines = new SafeMap(); | @@ -143,6 +144,7 @@ class TestCoverage { | 143 | 144 | coveredBranchPercent: 0, | 144 | 145 | coveredFunctionPercent: 0, | 145 | 146 | }, | | 147 | + thresholds: this.thresholds, | 146 | 148 | }; | 147 | 149 |
| 148 | 150 | if (!coverage) { | @@ -505,6 +507,12 @@ function setupCoverage(options) { | 505 | 507 | cwd, | 506 | 508 | options.coverageExcludeGlobs, | 507 | 509 | options.coverageIncludeGlobs, | | 510 | + { | | 511 | + __proto__: null, | | 512 | + line: options.lineCoverage, | | 513 | + branch: options.branchCoverage, | | 514 | + function: options.functionCoverage, | | 515 | + }, | 508 | 516 | ); | 509 | 517 | } | 510 | 518 |
| |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/test_runner/test.js +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1043,8 +1043,6 @@ class Test extends AsyncResource { | 1043 | 1043 | reporter.diagnostic(nesting, loc, `duration_ms ${this.duration()}`); | 1044 | 1044 |
| 1045 | 1045 | if (coverage) { | 1046 | | - reporter.coverage(nesting, loc, coverage); | 1047 | | - | 1048 | 1046 | const coverages = [ | 1049 | 1047 | { __proto__: null, actual: coverage.totals.coveredLinePercent, | 1050 | 1048 | threshold: this.config.lineCoverage, name: 'line' }, | @@ -1063,6 +1061,8 @@ class Test extends AsyncResource { | 1063 | 1061 | reporter.diagnostic(nesting, loc, `Error: ${NumberPrototypeToFixed(actual, 2)}% ${name} coverage does not meet threshold of ${threshold}%.`); | 1064 | 1062 | } | 1065 | 1063 | } | | 1064 | + | | 1065 | + reporter.coverage(nesting, loc, coverage); | 1066 | 1066 | } | 1067 | 1067 |
| 1068 | 1068 | if (harness.watching) { | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-runner-coverage-thresholds.js +45-12Lines changed: 45 additions & 12 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -44,10 +44,7 @@ function getTapCoverageFixtureReport() { | 44 | 44 | } | 45 | 45 |
| 46 | 46 | 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'); | 51 | 48 |
| 52 | 49 | const coverages = [ | 53 | 50 | { flag: '--test-coverage-lines', name: 'line', actual: 78.35 }, | @@ -56,10 +53,12 @@ const coverages = [ | 56 | 53 | ]; | 57 | 54 |
| 58 | 55 | for (const coverage of coverages) { | 59 | | - test(`test passing ${coverage.flag}`, async (t) => { | | 56 | + test(`test passing ${coverage.flag}`, () => { | 60 | 57 | const result = spawnSync(process.execPath, [ | 61 | | - ...neededArguments, | | 58 | + '--test', | | 59 | + '--experimental-test-coverage', | 62 | 60 | `${coverage.flag}=25`, | | 61 | + '--test-reporter', 'tap', | 63 | 62 | fixture, | 64 | 63 | ]); | 65 | 64 |
| @@ -70,10 +69,27 @@ for (const coverage of coverages) { | 70 | 69 | assert(!findCoverageFileForPid(result.pid)); | 71 | 70 | }); | 72 | 71 |
| 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}`, () => { | 74 | 88 | const result = spawnSync(process.execPath, [ | 75 | | - ...neededArguments, | | 89 | + '--test', | | 90 | + '--experimental-test-coverage', | 76 | 91 | `${coverage.flag}=99`, | | 92 | + '--test-reporter', 'tap', | 77 | 93 | fixture, | 78 | 94 | ]); | 79 | 95 |
| @@ -84,9 +100,25 @@ for (const coverage of coverages) { | 84 | 100 | assert(!findCoverageFileForPid(result.pid)); | 85 | 101 | }); | 86 | 102 |
| 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)`, () => { | 88 | 119 | const result = spawnSync(process.execPath, [ | 89 | | - ...neededArguments, | | 120 | + '--test', | | 121 | + '--experimental-test-coverage', | 90 | 122 | `${coverage.flag}=101`, | 91 | 123 | fixture, | 92 | 124 | ]); | @@ -96,9 +128,10 @@ for (const coverage of coverages) { | 96 | 128 | assert(!findCoverageFileForPid(result.pid)); | 97 | 129 | }); | 98 | 130 |
| 99 | | - test(`test out-of-range ${coverage.flag} (too low)`, async (t) => { | | 131 | + test(`test out-of-range ${coverage.flag} (too low)`, () => { | 100 | 132 | const result = spawnSync(process.execPath, [ | 101 | | - ...neededArguments, | | 133 | + '--test', | | 134 | + '--experimental-test-coverage', | 102 | 135 | `${coverage.flag}=-1`, | 103 | 136 | fixture, | 104 | 137 | ]); | |
|