diff --git a/doc/api/cli.md b/doc/api/cli.md index 2002a99654c1e0..67efe1d234de1c 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -2290,6 +2290,7 @@ This option may be specified multiple times to exclude multiple glob patterns. If both `--test-coverage-exclude` and `--test-coverage-include` are provided, files must meet **both** criteria to be included in the coverage report. +However, if there is an overlap between the two, `--test-coverage-include` takes precedence. ### `--test-coverage-functions=threshold` @@ -2318,6 +2319,10 @@ This option may be specified multiple times to include multiple glob patterns. If both `--test-coverage-exclude` and `--test-coverage-include` are provided, files must meet **both** criteria to be included in the coverage report. +However, if there is an overlap between the two, `--test-coverage-include` takes precedence. + +By default, the test files are excluded from code coverage. They can be explicitly +included via this flag. ### `--test-coverage-lines=threshold` diff --git a/doc/api/test.md b/doc/api/test.md index f88d3542f954bf..2774edbd0708df 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -1341,14 +1341,18 @@ changes: * `coverageExcludeGlobs` {string|Array} Excludes specific files from code coverage using a glob pattern, which can match both absolute and relative file paths. This property is only applicable when `coverage` was set to `true`. - If both `coverageExcludeGlobs` and `coverageIncludeGlobs` are provided, + If both `--test-coverage-exclude` and `--test-coverage-include` are provided, files must meet **both** criteria to be included in the coverage report. + However, if there is an overlap between the two, `--test-coverage-include` takes precedence. **Default:** `undefined`. * `coverageIncludeGlobs` {string|Array} Includes specific files in code coverage using a glob pattern, which can match both absolute and relative file paths. This property is only applicable when `coverage` was set to `true`. - If both `coverageExcludeGlobs` and `coverageIncludeGlobs` are provided, + If both `--test-coverage-exclude` and `--test-coverage-include` are provided, files must meet **both** criteria to be included in the coverage report. + However, if there is an overlap between the two, `--test-coverage-include` takes precedence. + By default, the test files are excluded from code coverage. They can be explicitly + included via this flag. **Default:** `undefined`. * `lineCoverage` {number} Require a minimum percent of covered lines. If code coverage does not reach the threshold specified, the process will exit with code `1`. diff --git a/lib/internal/test_runner/coverage.js b/lib/internal/test_runner/coverage.js index c27b34b9c762c4..4968f05f3ba2b5 100644 --- a/lib/internal/test_runner/coverage.js +++ b/lib/internal/test_runner/coverage.js @@ -25,9 +25,9 @@ const { readFileSync, rmSync, } = require('fs'); -const { setupCoverageHooks } = require('internal/util'); +const { setupCoverageHooks, isWindows, isMacOS } = require('internal/util'); const { tmpdir } = require('os'); -const { join, resolve, relative, matchesGlob } = require('path'); +const { join, resolve, relative } = require('path'); const { fileURLToPath } = require('internal/url'); const { kMappings, SourceMap } = require('internal/source_map/source_map'); const { @@ -42,6 +42,25 @@ const kLineEndingRegex = /\r?\n$/u; const kLineSplitRegex = /(?<=\r?\n)/u; const kStatusRegex = /\/\* node:coverage (?enable|disable) \*\//; +let minimatch; +function lazyMinimatch() { + minimatch ??= require('internal/deps/minimatch/index'); + return minimatch; +} + +function glob(path, pattern, windows) { + return lazyMinimatch().minimatch(path, pattern, { + __proto__: null, + nocase: isMacOS || isWindows, + windowsPathsNoEscape: true, + nonegate: true, + nocomment: true, + optimizationLevel: 2, + platform: windows ? 'win32' : 'posix', + nocaseMagicOnly: true, + }); +} + class CoverageLine { constructor(line, startOffset, src, length = src?.length) { const newlineLength = src == null ? 0 : @@ -464,23 +483,24 @@ class TestCoverage { coverageExcludeGlobs: excludeGlobs, coverageIncludeGlobs: includeGlobs, } = this.options; - // This check filters out files that match the exclude globs. - if (excludeGlobs?.length > 0) { - for (let i = 0; i < excludeGlobs.length; ++i) { - if (matchesGlob(relativePath, excludeGlobs[i]) || - matchesGlob(absolutePath, excludeGlobs[i])) return true; - } - } // This check filters out files that do not match the include globs. if (includeGlobs?.length > 0) { for (let i = 0; i < includeGlobs.length; ++i) { - if (matchesGlob(relativePath, includeGlobs[i]) || - matchesGlob(absolutePath, includeGlobs[i])) return false; + if (glob(relativePath, includeGlobs[i]) || + glob(absolutePath, includeGlobs[i])) return false; } return true; } + // This check filters out files that match the exclude globs. + if (excludeGlobs?.length > 0) { + for (let i = 0; i < excludeGlobs.length; ++i) { + if (glob(relativePath, excludeGlobs[i]) || + glob(absolutePath, excludeGlobs[i])) return true; + } + } + // This check filters out the node_modules/ directory, unless it is explicitly included. return StringPrototypeIncludes(url, '/node_modules/'); } diff --git a/lib/internal/test_runner/harness.js b/lib/internal/test_runner/harness.js index e9356cbc0100bb..93946cfb19d55d 100644 --- a/lib/internal/test_runner/harness.js +++ b/lib/internal/test_runner/harness.js @@ -249,6 +249,13 @@ function setupProcessState(root, globalOptions) { root.harness.teardown = exitHandler; } +function excludeTestFileFromCoverage(testFile, globalOptions) { + if (globalOptions.coverageExcludeGlobs === undefined) { + globalOptions.coverageExcludeGlobs = []; + } + ArrayPrototypePush(globalOptions.coverageExcludeGlobs, testFile); +} + function lazyBootstrapRoot() { if (!globalRoot) { // This is where the test runner is bootstrapped when node:test is used @@ -261,6 +268,7 @@ function lazyBootstrapRoot() { }; const globalOptions = parseCommandLine(); globalOptions.cwd = process.cwd(); + excludeTestFileFromCoverage(entryFile, globalOptions); createTestTree(rootTestOptions, globalOptions); globalRoot.reporter.on('test:summary', (data) => { if (!data.success) { diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js index 43a62b5b4307e4..6658abb74410b6 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -664,6 +664,12 @@ function run(options = kEmptyObject) { validateStringArray(argv, 'options.argv'); validateStringArray(execArgv, 'options.execArgv'); + let testFiles = files ?? createTestFileList(globPatterns, cwd); + if (coverageExcludeGlobs === undefined) { + coverageExcludeGlobs = []; + } + ArrayPrototypePush(coverageExcludeGlobs, ...testFiles); + const rootTestOptions = { __proto__: null, concurrency, timeout, signal }; const globalOptions = { __proto__: null, @@ -680,7 +686,6 @@ function run(options = kEmptyObject) { cwd, }; const root = createTestTree(rootTestOptions, globalOptions); - let testFiles = files ?? createTestFileList(globPatterns, cwd); if (shard) { testFiles = ArrayPrototypeFilter(testFiles, (_, index) => index % shard.total === shard.index - 1); diff --git a/test/fixtures/test-runner/output/coverage-width-100-uncovered-lines.snapshot b/test/fixtures/test-runner/output/coverage-width-100-uncovered-lines.snapshot index c410c42fb7eeb9..db40b664c8c682 100644 --- a/test/fixtures/test-runner/output/coverage-width-100-uncovered-lines.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-100-uncovered-lines.snapshot @@ -15,18 +15,16 @@ ok 1 - Coverage Print Fixed Width 100 # duration_ms * # start of coverage report # -------------------------------------------------------------------------------------------------- -# file | line % | branch % | funcs % | uncovered lines +# file | line % | branch % | funcs % | uncovered lines # -------------------------------------------------------------------------------------------------- -# test | | | | -# fixtures | | | | -# test-runner | | | | -# coverage-snap | | | | -# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 … -# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 -# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 … -# output | | | | -# coverage-width-100-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 | +# test | | | | +# fixtures | | | | +# test-runner | | | | +# coverage-snap | | | | +# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-… +# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 +# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-… # -------------------------------------------------------------------------------------------------- -# all files | 52.80 | 60.00 | 1.61 | +# all files | 51.44 | 55.56 | 1.61 | # -------------------------------------------------------------------------------------------------- # end of coverage report diff --git a/test/fixtures/test-runner/output/coverage-width-100.snapshot b/test/fixtures/test-runner/output/coverage-width-100.snapshot index dfb48005c48eaf..659e2c64e34d85 100644 --- a/test/fixtures/test-runner/output/coverage-width-100.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-100.snapshot @@ -14,18 +14,16 @@ ok 1 - Coverage Print Fixed Width 100 # todo 0 # duration_ms * # start of coverage report -# -------------------------------------------------------------------------------------------------- -# file | line % | branch % | funcs % | uncovered lines -# -------------------------------------------------------------------------------------------------- -# test | | | | -# fixtures | | | | -# test-runner | | | | -# coverage-snap | | | | -# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-4… -# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 -# output | | | | -# coverage-width-100.mjs | 100.00 | 100.00 | 100.00 | -# -------------------------------------------------------------------------------------------------- -# all files | 60.81 | 100.00 | 0.00 | -# -------------------------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------------------------- +# file | line % | branch % | funcs % | uncovered lines +# ----------------------------------------------------------------------------------------------- +# test | | | | +# fixtures | | | | +# test-runner | | | | +# coverage-snap | | | | +# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 +# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 +# ----------------------------------------------------------------------------------------------- +# all files | 53.97 | 100.00 | 0.00 | +# ----------------------------------------------------------------------------------------------- # end of coverage report diff --git a/test/fixtures/test-runner/output/coverage-width-150-uncovered-lines.snapshot b/test/fixtures/test-runner/output/coverage-width-150-uncovered-lines.snapshot index 423dac3291bf74..65bdd260faad62 100644 --- a/test/fixtures/test-runner/output/coverage-width-150-uncovered-lines.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-150-uncovered-lines.snapshot @@ -15,18 +15,16 @@ ok 1 - Coverage Print Fixed Width 150 # duration_ms * # start of coverage report # ---------------------------------------------------------------------------------------------------------------------------------------------------- -# file | line % | branch % | funcs % | uncovered lines +# file | line % | branch % | funcs % | uncovered lines # ---------------------------------------------------------------------------------------------------------------------------------------------------- -# test | | | | -# fixtures | | | | -# test-runner | | | | -# coverage-snap | | | | -# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 -# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 -# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-61 63-65 67-69 91… -# output | | | | -# coverage-width-150-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 | +# test | | | | +# fixtures | | | | +# test-runner | | | | +# coverage-snap | | | | +# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 +# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 +# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-61 63-65 67-69 91-93 96-98 100-1… # ---------------------------------------------------------------------------------------------------------------------------------------------------- -# all files | 52.80 | 60.00 | 1.61 | +# all files | 51.44 | 55.56 | 1.61 | # ---------------------------------------------------------------------------------------------------------------------------------------------------- # end of coverage report diff --git a/test/fixtures/test-runner/output/coverage-width-150.snapshot b/test/fixtures/test-runner/output/coverage-width-150.snapshot index c4aa8109955a12..b5ad47826d2e28 100644 --- a/test/fixtures/test-runner/output/coverage-width-150.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-150.snapshot @@ -14,18 +14,16 @@ ok 1 - Coverage Print Fixed Width 150 # todo 0 # duration_ms * # start of coverage report -# -------------------------------------------------------------------------------------------------------- -# file | line % | branch % | funcs % | uncovered lines -# -------------------------------------------------------------------------------------------------------- -# test | | | | -# fixtures | | | | -# test-runner | | | | -# coverage-snap | | | | -# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 -# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 -# output | | | | -# coverage-width-150.mjs | 100.00 | 100.00 | 100.00 | -# -------------------------------------------------------------------------------------------------------- -# all files | 60.81 | 100.00 | 0.00 | -# -------------------------------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------------------------- +# file | line % | branch % | funcs % | uncovered lines +# ----------------------------------------------------------------------------------------------- +# test | | | | +# fixtures | | | | +# test-runner | | | | +# coverage-snap | | | | +# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 +# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 +# ----------------------------------------------------------------------------------------------- +# all files | 53.97 | 100.00 | 0.00 | +# ----------------------------------------------------------------------------------------------- # end of coverage report diff --git a/test/fixtures/test-runner/output/coverage-width-40.snapshot b/test/fixtures/test-runner/output/coverage-width-40.snapshot index 09d236b8bea413..79ccc4b537bce8 100644 --- a/test/fixtures/test-runner/output/coverage-width-40.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-40.snapshot @@ -25,9 +25,7 @@ ok 1 - Coverage Print Fixed Width 40 # c.js | 55.77 | 100.00 | 0.00 | … # a.js | 55.77 | 100.00 | 0.00 | … # b.js | 45.45 | 100.00 | 0.00 | … -# output | | | | -# …e-width-40.mjs | 100.00 | 100.00 | 100.00 | # -------------------------------------- -# all files | 59.06 | 100.00 | 0.00 | +# all files | 54.78 | 100.00 | 0.00 | # -------------------------------------- # end of coverage report diff --git a/test/fixtures/test-runner/output/coverage-width-80-color.snapshot b/test/fixtures/test-runner/output/coverage-width-80-color.snapshot index eb94b331a18001..25c615a4e1261d 100644 --- a/test/fixtures/test-runner/output/coverage-width-80-color.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-80-color.snapshot @@ -9,18 +9,16 @@ [34mℹ duration_ms *[39m [34mℹ start of coverage report ℹ ------------------------------------------------------------------------------ -ℹ file | [31mline %[34m | [31mbranch %[34m | [31mfuncs %[34m | uncovered … +ℹ file | [31mline %[34m | [31mbranch %[34m | [31mfuncs %[34m | uncovered lines ℹ ------------------------------------------------------------------------------ -ℹ test | [31m [34m | [31m [34m | [31m [34m | -ℹ fixtures | [31m [34m | [31m [34m | [31m [34m | -ℹ test-runner | [31m [34m | [31m [34m | [31m [34m | -ℹ coverage-snap | [31m [34m | [31m [34m | [31m [34m | -ℹ [33ma.js [34m | [33m 55.77[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 1… -ℹ [31mb.js [34m | [31m 45.45[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 -ℹ output | [31m [34m | [31m [34m | [31m [34m | -ℹ [32mcoverage-width-80-color.mjs [34m | [32m100.00[34m | [32m 100.00[34m | [32m 100.00[34m | +ℹ test | [31m [34m | [31m [34m | [31m [34m | +ℹ fixtures | [31m [34m | [31m [34m | [31m [34m | +ℹ test-runner | [31m [34m | [31m [34m | [31m [34m | +ℹ coverage-snap | [31m [34m | [31m [34m | [31m [34m | +ℹ [33ma.js [34m | [33m 55.77[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 13-15 17-19 29-… +ℹ [31mb.js [34m | [31m 45.45[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 ℹ ------------------------------------------------------------------------------ -ℹ all files | [33m 61.33[34m | [32m 100.00[34m | [31m 0.00[34m | +ℹ all files | [33m 53.97[34m | [32m 100.00[34m | [31m 0.00[34m | ℹ ------------------------------------------------------------------------------ ℹ end of coverage report [39m \ No newline at end of file diff --git a/test/fixtures/test-runner/output/coverage-width-80-uncovered-lines-color.snapshot b/test/fixtures/test-runner/output/coverage-width-80-uncovered-lines-color.snapshot index b9e56fca6586ac..2de7a90706fa84 100644 --- a/test/fixtures/test-runner/output/coverage-width-80-uncovered-lines-color.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-80-uncovered-lines-color.snapshot @@ -9,19 +9,17 @@ [34mℹ duration_ms *[39m [34mℹ start of coverage report ℹ -------------------------------------------------------------------------------------------------- -ℹ file | [31mline %[34m | [31mbranch %[34m | [31mfuncs %[34m | uncovered lines +ℹ file | [31mline %[34m | [31mbranch %[34m | [31mfuncs %[34m | uncovered lines ℹ -------------------------------------------------------------------------------------------------- -ℹ test | [31m [34m | [31m [34m | [31m [34m | -ℹ fixtures | [31m [34m | [31m [34m | [31m [34m | -ℹ test-runner | [31m [34m | [31m [34m | [31m [34m | -ℹ coverage-snap | [31m [34m | [31m [34m | [31m [34m | -ℹ [33ma.js [34m | [33m 55.77[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 13-15… -ℹ [31mb.js [34m | [31m 45.45[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 -ℹ [31mmany-uncovered-lines.js [34m | [33m 50.99[34m | [31m 42.86[34m | [31m 1.92[34m | 5-7 9-11 13-15… -ℹ output | [31m [34m | [31m [34m | [31m [34m | -ℹ [32mcoverage-width-80-uncovered-lines-color.mjs [34m | [32m100.00[34m | [32m 100.00[34m | [32m 100.00[34m | +ℹ test | [31m [34m | [31m [34m | [31m [34m | +ℹ fixtures | [31m [34m | [31m [34m | [31m [34m | +ℹ test-runner | [31m [34m | [31m [34m | [31m [34m | +ℹ coverage-snap | [31m [34m | [31m [34m | [31m [34m | +ℹ [33ma.js [34m | [33m 55.77[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 13-15 17-19 29-30 40-42 4… +ℹ [31mb.js [34m | [31m 45.45[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 +ℹ [31mmany-uncovered-lines.js [34m | [33m 50.99[34m | [31m 42.86[34m | [31m 1.92[34m | 5-7 9-11 13-15 17-19 29-30 40-42 4… ℹ -------------------------------------------------------------------------------------------------- -ℹ all files | [33m 52.91[34m | [33m 60.00[34m | [31m 1.61[34m | +ℹ all files | [33m 51.44[34m | [33m 55.56[34m | [31m 1.61[34m | ℹ -------------------------------------------------------------------------------------------------- ℹ end of coverage report [39m \ No newline at end of file diff --git a/test/fixtures/test-runner/output/coverage-width-80-uncovered-lines.snapshot b/test/fixtures/test-runner/output/coverage-width-80-uncovered-lines.snapshot index 6564d7942d8cd9..db40b664c8c682 100644 --- a/test/fixtures/test-runner/output/coverage-width-80-uncovered-lines.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-80-uncovered-lines.snapshot @@ -15,18 +15,16 @@ ok 1 - Coverage Print Fixed Width 100 # duration_ms * # start of coverage report # -------------------------------------------------------------------------------------------------- -# file | line % | branch % | funcs % | uncovered lines +# file | line % | branch % | funcs % | uncovered lines # -------------------------------------------------------------------------------------------------- -# test | | | | -# fixtures | | | | -# test-runner | | | | -# coverage-snap | | | | -# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 2… -# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 -# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 2… -# output | | | | -# coverage-width-80-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 | +# test | | | | +# fixtures | | | | +# test-runner | | | | +# coverage-snap | | | | +# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-… +# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 +# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-… # -------------------------------------------------------------------------------------------------- -# all files | 52.80 | 60.00 | 1.61 | +# all files | 51.44 | 55.56 | 1.61 | # -------------------------------------------------------------------------------------------------- # end of coverage report diff --git a/test/fixtures/test-runner/output/coverage-width-80.snapshot b/test/fixtures/test-runner/output/coverage-width-80.snapshot index de071277e1f98d..fd8faf99b536ae 100644 --- a/test/fixtures/test-runner/output/coverage-width-80.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-80.snapshot @@ -15,17 +15,15 @@ ok 1 - Coverage Print Fixed Width 80 # duration_ms * # start of coverage report # ------------------------------------------------------------------------------ -# file | line % | branch % | funcs % | uncovered lines +# file | line % | branch % | funcs % | uncovered lines # ------------------------------------------------------------------------------ -# test | | | | -# fixtures | | | | -# test-runner | | | | -# coverage-snap | | | | -# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-… -# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 -# output | | | | -# coverage-width-80.mjs | 100.00 | 100.00 | 100.00 | +# test | | | | +# fixtures | | | | +# test-runner | | | | +# coverage-snap | | | | +# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30… +# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 # ------------------------------------------------------------------------------ -# all files | 60.81 | 100.00 | 0.00 | +# all files | 53.97 | 100.00 | 0.00 | # ------------------------------------------------------------------------------ # end of coverage report diff --git a/test/fixtures/test-runner/output/coverage-width-infinity-uncovered-lines.snapshot b/test/fixtures/test-runner/output/coverage-width-infinity-uncovered-lines.snapshot index 7440b7772a1925..b4f2c87dd72a7d 100644 --- a/test/fixtures/test-runner/output/coverage-width-infinity-uncovered-lines.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-infinity-uncovered-lines.snapshot @@ -14,19 +14,17 @@ ok 1 - Coverage Print Fixed Width Infinity # todo 0 # duration_ms * # start of coverage report -# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# file | line % | branch % | funcs % | uncovered lines -# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# test | | | | -# fixtures | | | | -# test-runner | | | | -# coverage-snap | | | | -# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 -# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 -# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-61 63-65 67-69 91-93 96-98 100-102 104-106 111-112 118-119 122-123 127-129 132-136 144-146 150 166-167 173 180 188-189 196-200 207-213 216-218 221-223 226-228 232 236-238 241-243 246-248 251-257 260-262 265-268 271-273 276-280 283-285 288-290 293-295 298-301 304-306 309-312 315-318 321-324 327-329 332-340 343-348 351-353 -# output | | | | -# coverage-width-infinity-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 | -# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# all files | 52.80 | 60.00 | 1.61 | -# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +# file | line % | branch % | funcs % | uncovered lines +# ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +# test | | | | +# fixtures | | | | +# test-runner | | | | +# coverage-snap | | | | +# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 +# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 +# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-61 63-65 67-69 91-93 96-98 100-102 104-106 111-112 118-119 122-123 127-129 132-136 144-146 150 166-167 173 180 188-189 196-200 207-213 216-218 221-223 226-228 232 236-238 241-243 246-248 251-257 260-262 265-268 271-273 276-280 283-285 288-290 293-295 298-301 304-306 309-312 315-318 321-324 327-329 332-340 343-348 351-353 +# ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +# all files | 51.44 | 55.56 | 1.61 | +# ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # end of coverage report diff --git a/test/fixtures/test-runner/output/coverage-width-infinity.snapshot b/test/fixtures/test-runner/output/coverage-width-infinity.snapshot index 2b9916a5b08217..9a9d5dedc94b8b 100644 --- a/test/fixtures/test-runner/output/coverage-width-infinity.snapshot +++ b/test/fixtures/test-runner/output/coverage-width-infinity.snapshot @@ -14,18 +14,16 @@ ok 1 - Coverage Print Fixed Width Infinity # todo 0 # duration_ms * # start of coverage report -# ------------------------------------------------------------------------------------------------------------- -# file | line % | branch % | funcs % | uncovered lines -# ------------------------------------------------------------------------------------------------------------- -# test | | | | -# fixtures | | | | -# test-runner | | | | -# coverage-snap | | | | -# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 -# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 -# output | | | | -# coverage-width-infinity.mjs | 100.00 | 100.00 | 100.00 | -# ------------------------------------------------------------------------------------------------------------- -# all files | 60.81 | 100.00 | 0.00 | -# ------------------------------------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------------------------- +# file | line % | branch % | funcs % | uncovered lines +# ----------------------------------------------------------------------------------------------- +# test | | | | +# fixtures | | | | +# test-runner | | | | +# coverage-snap | | | | +# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 +# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11 +# ----------------------------------------------------------------------------------------------- +# all files | 53.97 | 100.00 | 0.00 | +# ----------------------------------------------------------------------------------------------- # end of coverage report diff --git a/test/fixtures/test-runner/output/lcov_reporter.js b/test/fixtures/test-runner/output/lcov_reporter.js index a6d17432d18c23..469f1a7fb5035c 100644 --- a/test/fixtures/test-runner/output/lcov_reporter.js +++ b/test/fixtures/test-runner/output/lcov_reporter.js @@ -4,4 +4,13 @@ const fixtures = require('../../../common/fixtures'); const spawn = require('node:child_process').spawn; spawn(process.execPath, - ['--no-warnings', '--experimental-test-coverage', '--test-reporter', 'lcov', fixtures.path('test-runner/output/output.js')], { stdio: 'inherit' }); + [ + '--no-warnings', + '--experimental-test-coverage', + '--test-coverage-include=**', // Include also test files + '--test-reporter', + 'lcov', + fixtures.path('test-runner/output/output.js') + ], + { stdio: 'inherit' } +); diff --git a/test/parallel/test-runner-coverage-source-map.js b/test/parallel/test-runner-coverage-source-map.js index 48807fb2d193b4..9597fc58cc6f13 100644 --- a/test/parallel/test-runner-coverage-source-map.js +++ b/test/parallel/test-runner-coverage-source-map.js @@ -20,6 +20,7 @@ function generateReport(report) { const flags = [ '--enable-source-maps', + '--test-coverage-include=**', // Include also test files '--test', '--experimental-test-coverage', '--test-reporter', 'tap', ]; diff --git a/test/parallel/test-runner-coverage-thresholds.js b/test/parallel/test-runner-coverage-thresholds.js index c1b64cb06a83ff..0f45f596bcf563 100644 --- a/test/parallel/test-runner-coverage-thresholds.js +++ b/test/parallel/test-runner-coverage-thresholds.js @@ -62,6 +62,7 @@ for (const coverage of coverages) { '--test', '--experimental-test-coverage', `${coverage.flag}=25`, + '--test-coverage-include=**', // Include also test files '--test-reporter', 'tap', fixture, ]); @@ -78,6 +79,7 @@ for (const coverage of coverages) { '--test', '--experimental-test-coverage', `${coverage.flag}=25`, + '--test-coverage-include=**', // Include also test files '--test-reporter', reporter, fixture, ]); @@ -93,6 +95,7 @@ for (const coverage of coverages) { '--test', '--experimental-test-coverage', `${coverage.flag}=99`, + '--test-coverage-include=**', // Include also test files '--test-reporter', 'tap', fixture, ]); @@ -109,6 +112,7 @@ for (const coverage of coverages) { '--test', '--experimental-test-coverage', `${coverage.flag}=99`, + '--test-coverage-include=**', // Include also test files '--test-reporter', reporter, fixture, ]); @@ -123,6 +127,7 @@ for (const coverage of coverages) { const result = spawnSync(process.execPath, [ '--test', '--experimental-test-coverage', + '--test-coverage-include=**', // Include also test files `${coverage.flag}=101`, fixture, ]); @@ -136,6 +141,7 @@ for (const coverage of coverages) { const result = spawnSync(process.execPath, [ '--test', '--experimental-test-coverage', + '--test-coverage-include=**', // Include also test files `${coverage.flag}=-1`, fixture, ]); diff --git a/test/parallel/test-runner-coverage.js b/test/parallel/test-runner-coverage.js index 5756f1d237605c..db7463d995be67 100644 --- a/test/parallel/test-runner-coverage.js +++ b/test/parallel/test-runner-coverage.js @@ -25,19 +25,18 @@ function getTapCoverageFixtureReport() { const report = [ '# start of coverage report', - '# --------------------------------------------------------------------------------------------', + '# ------------------------------------------------------------------', '# file | line % | branch % | funcs % | uncovered lines', - '# --------------------------------------------------------------------------------------------', + '# ------------------------------------------------------------------', '# test | | | | ', '# fixtures | | | | ', '# test-runner | | | | ', - '# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72', '# invalid-tap.js | 100.00 | 100.00 | 100.00 | ', '# v8-coverage | | | | ', '# throw.js | 71.43 | 50.00 | 100.00 | 5-6', - '# --------------------------------------------------------------------------------------------', - '# all files | 78.35 | 43.75 | 60.00 | ', - '# --------------------------------------------------------------------------------------------', + '# ------------------------------------------------------------------', + '# all files | 75.00 | 66.67 | 100.00 | ', + '# ------------------------------------------------------------------', '# end of coverage report', ].join('\n'); @@ -53,19 +52,18 @@ function getSpecCoverageFixtureReport() { const report = [ '\u2139 start of coverage report', - '\u2139 --------------------------------------------------------------------------------------------', + '\u2139 ------------------------------------------------------------------', '\u2139 file | line % | branch % | funcs % | uncovered lines', - '\u2139 --------------------------------------------------------------------------------------------', + '\u2139 ------------------------------------------------------------------', '\u2139 test | | | | ', '\u2139 fixtures | | | | ', '\u2139 test-runner | | | | ', - '\u2139 coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72', '\u2139 invalid-tap.js | 100.00 | 100.00 | 100.00 | ', '\u2139 v8-coverage | | | | ', '\u2139 throw.js | 71.43 | 50.00 | 100.00 | 5-6', - '\u2139 --------------------------------------------------------------------------------------------', - '\u2139 all files | 78.35 | 43.75 | 60.00 | ', - '\u2139 --------------------------------------------------------------------------------------------', + '\u2139 ------------------------------------------------------------------', + '\u2139 all files | 75.00 | 66.67 | 100.00 | ', + '\u2139 ------------------------------------------------------------------', '\u2139 end of coverage report', ].join('\n'); @@ -164,19 +162,17 @@ test('single process coverage is the same with --test', skipIfNoInspector, () => test('coverage is combined for multiple processes', skipIfNoInspector, () => { let report = [ '# start of coverage report', - '# -------------------------------------------------------------------', - '# file | line % | branch % | funcs % | uncovered lines', - '# -------------------------------------------------------------------', - '# common.js | 89.86 | 62.50 | 100.00 | 8 13-14 18 34-35 53', - '# first.test.js | 83.33 | 100.00 | 50.00 | 5-6', - '# second.test.js | 100.00 | 100.00 | 100.00 | ', - '# third.test.js | 100.00 | 100.00 | 100.00 | ', - '# -------------------------------------------------------------------', - '# all files | 92.11 | 72.73 | 88.89 | ', - '# -------------------------------------------------------------------', + '# --------------------------------------------------------------', + '# file | line % | branch % | funcs % | uncovered lines', + '# --------------------------------------------------------------', + '# common.js | 89.86 | 62.50 | 100.00 | 8 13-14 18 34-35 53', + '# --------------------------------------------------------------', + '# all files | 89.86 | 62.50 | 100.00 | ', + '# --------------------------------------------------------------', '# end of coverage report', ].join('\n'); + if (common.isWindows) { report = report.replaceAll('/', '\\'); } @@ -195,6 +191,7 @@ test('coverage is combined for multiple processes', skipIfNoInspector, () => { assert.strictEqual(result.status, 0); }); +// TODO(pmarchini): is this skip still needed? test.skip('coverage works with isolation=none', skipIfNoInspector, () => { // There is a bug in coverage calculation. The branch % in the common.js // fixture is different depending on the test isolation mode. The 'none' mode @@ -236,9 +233,14 @@ test.skip('coverage works with isolation=none', skipIfNoInspector, () => { test('coverage reports on lines, functions, and branches', skipIfNoInspector, async (t) => { const fixture = fixtures.path('test-runner', 'coverage.js'); const child = spawnSync(process.execPath, - ['--test', '--experimental-test-coverage', '--test-reporter', - fixtures.fileURL('test-runner/custom_reporters/coverage.mjs'), - fixture]); + [ + '--test', + '--experimental-test-coverage', + '--test-reporter', + fixtures.fileURL('test-runner/custom_reporters/coverage.mjs'), + '--test-coverage-include=**', // Including also test file in the coverage report + fixture, + ]); assert.strictEqual(child.stderr.toString(), ''); const stdout = child.stdout.toString(); const coverage = JSON.parse(stdout); @@ -297,7 +299,6 @@ test('coverage with ESM hook - source irrelevant', skipIfNoInspector, () => { '# ------------------------------------------------------------------', '# hooks.mjs | 100.00 | 100.00 | 100.00 | ', '# register-hooks.js | 100.00 | 100.00 | 100.00 | ', - '# virtual.js | 100.00 | 100.00 | 100.00 | ', '# ------------------------------------------------------------------', '# all files | 100.00 | 100.00 | 100.00 | ', '# ------------------------------------------------------------------', @@ -310,7 +311,13 @@ test('coverage with ESM hook - source irrelevant', skipIfNoInspector, () => { const fixture = fixtures.path('test-runner', 'coverage-loader'); const args = [ - '--import', './register-hooks.js', '--test', '--experimental-test-coverage', '--test-reporter', 'tap', 'virtual.js', + '--import', + './register-hooks.js', + '--test', + '--experimental-test-coverage', + '--test-reporter', + 'tap', + 'virtual.js', ]; const result = spawnSync(process.execPath, args, { cwd: fixture }); @@ -327,7 +334,6 @@ test('coverage with ESM hook - source transpiled', skipIfNoInspector, () => { '# ------------------------------------------------------------------', '# hooks.mjs | 100.00 | 100.00 | 100.00 | ', '# register-hooks.js | 100.00 | 100.00 | 100.00 | ', - '# sum.test.ts | 100.00 | 100.00 | 100.00 | ', '# sum.ts | 100.00 | 100.00 | 100.00 | ', '# ------------------------------------------------------------------', '# all files | 100.00 | 100.00 | 100.00 | ', @@ -360,22 +366,19 @@ test('coverage with excluded files', skipIfNoInspector, () => { const result = spawnSync(process.execPath, args); const report = [ '# start of coverage report', - '# -----------------------------------------------------------------------------------------', + '# ---------------------------------------------------------------', '# file | line % | branch % | funcs % | uncovered lines', - '# -----------------------------------------------------------------------------------------', + '# ---------------------------------------------------------------', '# test | | | | ', '# fixtures | | | | ', - '# test-runner | | | | ', - '# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72', '# v8-coverage | | | | ', '# throw.js | 71.43 | 50.00 | 100.00 | 5-6', - '# -----------------------------------------------------------------------------------------', - '# all files | 78.13 | 40.00 | 60.00 | ', - '# -----------------------------------------------------------------------------------------', + '# ---------------------------------------------------------------', + '# all files | 71.43 | 50.00 | 100.00 | ', + '# ---------------------------------------------------------------', '# end of coverage report', ].join('\n'); - if (common.isWindows) { return report.replaceAll('/', '\\'); } @@ -425,7 +428,7 @@ test('coverage with included and excluded files', skipIfNoInspector, () => { const fixture = fixtures.path('test-runner', 'coverage.js'); const args = [ '--experimental-test-coverage', '--test-reporter', 'tap', - '--test-coverage-include=test/fixtures/test-runner/*.js', + '--test-coverage-include=test/fixtures/test-runner/!(*-tap).js', '--test-coverage-exclude=test/fixtures/test-runner/*-tap.js', fixture, ]; @@ -458,27 +461,31 @@ test('coverage with included and excluded files', skipIfNoInspector, () => { test('correctly prints the coverage report of files contained in parent directories', skipIfNoInspector, () => { let report = [ '# start of coverage report', - '# --------------------------------------------------------------------------------------------', + '# ------------------------------------------------------------------', '# file | line % | branch % | funcs % | uncovered lines', - '# --------------------------------------------------------------------------------------------', + '# ------------------------------------------------------------------', '# .. | | | | ', - '# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72', '# invalid-tap.js | 100.00 | 100.00 | 100.00 | ', '# .. | | | | ', '# v8-coverage | | | | ', '# throw.js | 71.43 | 50.00 | 100.00 | 5-6', - '# --------------------------------------------------------------------------------------------', - '# all files | 78.35 | 43.75 | 60.00 | ', - '# --------------------------------------------------------------------------------------------', + '# ------------------------------------------------------------------', + '# all files | 75.00 | 66.67 | 100.00 | ', + '# ------------------------------------------------------------------', '# end of coverage report', ].join('\n'); + if (common.isWindows) { report = report.replaceAll('/', '\\'); } const fixture = fixtures.path('test-runner', 'coverage.js'); const args = [ - '--test', '--experimental-test-coverage', '--test-reporter', 'tap', fixture, + '--test', + '--experimental-test-coverage', + '--test-reporter', + 'tap', + fixture, ]; const result = spawnSync(process.execPath, args, { env: { ...process.env, NODE_TEST_TMPDIR: tmpdir.path }, @@ -489,3 +496,71 @@ test('correctly prints the coverage report of files contained in parent director assert(result.stdout.toString().includes(report)); assert.strictEqual(result.status, 0); }); + +test('coverage should not include test files by default - lazyBootstrap', skipIfNoInspector, () => { + const fixture = fixtures.path('test-runner', 'coverage.js'); + const args = [ + '--experimental-test-coverage', '--test-reporter', 'tap', + fixture, + ]; + const result = spawnSync(process.execPath, args); + const report = [ + '# start of coverage report', + '# ------------------------------------------------------------------', + '# file | line % | branch % | funcs % | uncovered lines', + '# ------------------------------------------------------------------', + '# test | | | | ', + '# fixtures | | | | ', + '# test-runner | | | | ', + '# invalid-tap.js | 100.00 | 100.00 | 100.00 | ', + '# v8-coverage | | | | ', + '# throw.js | 71.43 | 50.00 | 100.00 | 5-6', + '# ------------------------------------------------------------------', + '# all files | 75.00 | 66.67 | 100.00 | ', + '# ------------------------------------------------------------------', + '# end of coverage report', + ].join('\n'); + + + if (common.isWindows) { + return report.replaceAll('/', '\\'); + } + + assert(result.stdout.toString().includes(report)); + assert.strictEqual(result.status, 0); + assert(!findCoverageFileForPid(result.pid)); +}); + +test('coverage should not include test files by default', skipIfNoInspector, () => { + const fixture = fixtures.path('test-runner', 'coverage.js'); + const args = [ + '--test', '--experimental-test-coverage', '--test-reporter', 'tap', + fixture, + ]; + const result = spawnSync(process.execPath, args); + const report = [ + '# start of coverage report', + '# ------------------------------------------------------------------', + '# file | line % | branch % | funcs % | uncovered lines', + '# ------------------------------------------------------------------', + '# test | | | | ', + '# fixtures | | | | ', + '# test-runner | | | | ', + '# invalid-tap.js | 100.00 | 100.00 | 100.00 | ', + '# v8-coverage | | | | ', + '# throw.js | 71.43 | 50.00 | 100.00 | 5-6', + '# ------------------------------------------------------------------', + '# all files | 75.00 | 66.67 | 100.00 | ', + '# ------------------------------------------------------------------', + '# end of coverage report', + ].join('\n'); + + + if (common.isWindows) { + return report.replaceAll('/', '\\'); + } + + assert(result.stdout.toString().includes(report)); + assert.strictEqual(result.status, 0); + assert(!findCoverageFileForPid(result.pid)); +}); diff --git a/test/parallel/test-runner-run-coverage.mjs b/test/parallel/test-runner-run-coverage.mjs index 15fcfef5238843..514c70b4b16341 100644 --- a/test/parallel/test-runner-run-coverage.mjs +++ b/test/parallel/test-runner-run-coverage.mjs @@ -139,7 +139,7 @@ describe('require(\'node:test\').run coverage settings', { concurrency: true }, const stream = run({ files: [...files, fixtures.path('test-runner/invalid-tap.js')], coverage: true, - coverageIncludeGlobs: ['test/fixtures/test-runner/*.js'], + coverageIncludeGlobs: ['test/fixtures/test-runner/!(*-tap).js'], coverageExcludeGlobs: ['test/fixtures/test-runner/*-tap.js'] }); stream.on('test:fail', common.mustNotCall()); @@ -157,7 +157,12 @@ describe('require(\'node:test\').run coverage settings', { concurrency: true }, const thresholdErrors = []; const originalExitCode = process.exitCode; assert.notStrictEqual(originalExitCode, 1); - const stream = run({ files, coverage: true, lineCoverage: 99, branchCoverage: 99, functionCoverage: 99 }); + const stream = run({ files, + coverage: true, + lineCoverage: 99, + branchCoverage: 99, + functionCoverage: 99, + coverageIncludeGlobs: ['**'] }); stream.on('test:fail', common.mustNotCall()); stream.on('test:pass', common.mustCall(1)); stream.on('test:diagnostic', ({ message }) => {