diff --git a/lib/internal/test_runner/utils.js b/lib/internal/test_runner/utils.js index 5a29673279311b..463ea81c44d5f8 100644 --- a/lib/internal/test_runner/utils.js +++ b/lib/internal/test_runner/utils.js @@ -75,6 +75,8 @@ if (getOptionValue('--strip-types')) { ArrayPrototypePush(kFileExtensions, 'ts', 'mts', 'cts'); } const kDefaultPattern = `**/{${ArrayPrototypeJoin(kPatterns, ',')}}.{${ArrayPrototypeJoin(kFileExtensions, ',')}}`; +const kDefaultCoverageDotfilePattern = + `test/{.*,**/.*}.{${ArrayPrototypeJoin(kFileExtensions, ',')}}`; function createDeferredCallback() { let calledCount = 0; @@ -403,7 +405,7 @@ function parseCommandLine() { if (!coverageExcludeGlobs || coverageExcludeGlobs.length === 0) { // TODO(pmarchini): this default should follow something similar to c8 defaults // Default exclusions should be also exported to be used by other tools / users - coverageExcludeGlobs = [kDefaultPattern]; + coverageExcludeGlobs = [kDefaultPattern, kDefaultCoverageDotfilePattern]; } coverageIncludeGlobs = getOptionValue('--test-coverage-include'); diff --git a/test/fixtures/test-runner/coverage-default-exclusion/test/.dotfile.cjs b/test/fixtures/test-runner/coverage-default-exclusion/test/.dotfile.cjs new file mode 100644 index 00000000000000..ec0a4c24fffb3a --- /dev/null +++ b/test/fixtures/test-runner/coverage-default-exclusion/test/.dotfile.cjs @@ -0,0 +1,7 @@ +const test = require('node:test'); +const assert = require('node:assert'); +const { foo } = require('../logic-file.js'); + +test('foo returns 1 from a dotfile test', () => { + assert.strictEqual(foo(), 1); +}); diff --git a/test/parallel/test-runner-coverage-default-exclusion.mjs b/test/parallel/test-runner-coverage-default-exclusion.mjs index 44e5f7600d3270..2ef6d81bf1dd9b 100644 --- a/test/parallel/test-runner-coverage-default-exclusion.mjs +++ b/test/parallel/test-runner-coverage-default-exclusion.mjs @@ -114,4 +114,34 @@ describe('test runner coverage default exclusion', skipIfNoInspector, () => { assert(result.stdout.toString().includes(report)); assert.strictEqual(result.status, 0); }); + + it('should exclude dotfile test files from coverage by default', async () => { + const report = [ + '# start of coverage report', + '# --------------------------------------------------------------', + '# file | line % | branch % | funcs % | uncovered lines', + '# --------------------------------------------------------------', + '# logic-file.js | 66.67 | 100.00 | 50.00 | 5-7', + '# --------------------------------------------------------------', + '# all files | 66.67 | 100.00 | 50.00 | ', + '# --------------------------------------------------------------', + '# end of coverage report', + ].join('\n'); + + const args = [ + '--no-experimental-strip-types', + '--test', + '--experimental-test-coverage', + '--test-reporter=tap', + 'test/.dotfile.cjs', + ]; + const result = spawnSync(process.execPath, args, { + env: { ...process.env, NODE_TEST_TMPDIR: tmpdir.path }, + cwd: tmpdir.path + }); + + assert.strictEqual(result.stderr.toString(), ''); + assert(result.stdout.toString().includes(report)); + assert.strictEqual(result.status, 0); + }); });