| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0d999e3 commit 28a775b
16 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1209,6 +1209,17 @@ Starts the Node.js command line test runner. This flag cannot be combined with | |||
| 1209 | 1209 | See the documentation on [running tests from the command line][] | |
| 1210 | 1210 | for more details. | |
| 1211 | 1211 | ||
| 1212 | + ### `--test-coverage` | ||
| 1213 | + | ||
| 1214 | + <!-- YAML | ||
| 1215 | + added: REPLACEME | ||
| 1216 | + --> | ||
| 1217 | + | ||
| 1218 | + When used in conjunction with the `node:test` module, a code coverage report is | ||
| 1219 | + generated as part of the test runner output. If no tests are run, a coverage | ||
| 1220 | + report is not generated. See the documentation on | ||
| 1221 | + [collecting code coverage from tests][] for more details. | ||
| 1222 | + | ||
| 1212 | 1223 | ### `--test-name-pattern` | |
| 1213 | 1224 | ||
| 1214 | 1225 | <!-- YAML | |
@@ -2316,6 +2327,7 @@ done | |||
| 2316 | 2327 | [`unhandledRejection`]: process.md#event-unhandledrejection | |
| 2317 | 2328 | [`v8.startupSnapshot` API]: v8.md#startup-snapshot-api | |
| 2318 | 2329 | [`worker_threads.threadId`]: worker_threads.md#workerthreadid | |
| 2330 | + [collecting code coverage from tests]: test.md#collecting-code-coverage | ||
| 2319 | 2331 | [conditional exports]: packages.md#conditional-exports | |
| 2320 | 2332 | [context-aware]: addons.md#context-aware-addons | |
| 2321 | 2333 | [customizing ESM specifier resolution]: esm.md#customizing-esm-specifier-resolution-algorithm | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -368,6 +368,54 @@ Otherwise, the test is considered to be a failure. Test files must be | |||
| 368 | 368 | executable by Node.js, but are not required to use the `node:test` module | |
| 369 | 369 | internally. | |
| 370 | 370 | ||
| 371 | + ## Collecting code coverage | ||
| 372 | + | ||
| 373 | + When Node.js is started with the [`--test-coverage`][] command-line flag, code | ||
| 374 | + coverage is collected and statistics are reported once all tests have completed. | ||
| 375 | + If the [`NODE_V8_COVERAGE`][] environment variable is used to specify a | ||
| 376 | + code coverage directory, the generated V8 coverage files are written to that | ||
| 377 | + directory. Node.js core modules and files within `node_modules/` directories | ||
| 378 | + are not included in the coverage report. If coverage is enabled, the coverage | ||
| 379 | + report is sent to any [test reporters][] via the `'test:coverage'` event. | ||
| 380 | + | ||
| 381 | + Coverage can be disabled on a series of lines using the following | ||
| 382 | + comment syntax: | ||
| 383 | + | ||
| 384 | + ```js | ||
| 385 | + /* node:coverage disable */ | ||
| 386 | + if (anAlwaysFalseCondition) { | ||
| 387 | + // Code in this branch will never be executed, but the lines are ignored for | ||
| 388 | + // coverage purposes. All lines following the 'disable' comment are ignored | ||
| 389 | + // until a corresponding 'enable' comment is encountered. | ||
| 390 | + console.log('this is never executed'); | ||
| 391 | + } | ||
| 392 | + /* node:coverage enable */ | ||
| 393 | + ``` | ||
| 394 | + | ||
| 395 | + Coverage can also be disabled for a specified number of lines. After the | ||
| 396 | + specified number of lines, coverage will be automatically reenabled. If the | ||
| 397 | + number of lines is not explicitly provided, a single line is ignored. | ||
| 398 | + | ||
| 399 | + ```js | ||
| 400 | + /* node:coverage ignore next */ | ||
| 401 | + if (anAlwaysFalseCondition) { console.log('this is never executed'); } | ||
| 402 | + | ||
| 403 | + /* node:coverage ignore next 3 */ | ||
| 404 | + if (anAlwaysFalseCondition) { | ||
| 405 | + console.log('this is never executed'); | ||
| 406 | + } | ||
| 407 | + ``` | ||
| 408 | + | ||
| 409 | + The test runner's code coverage functionality has the following limitations, | ||
| 410 | + which will be addressed in a future Node.js release: | ||
| 411 | + | ||
| 412 | + * Although coverage data is collected for child processes, this information is | ||
| 413 | + not included in the coverage report. Because the command line test runner uses | ||
| 414 | + child processes to execute test files, it cannot be used with `--test-coverage`. | ||
| 415 | + * Source maps are not supported. | ||
| 416 | + * Excluding specific files or directories from the coverage report is not | ||
| 417 | + supported. | ||
| 418 | + | ||
| 371 | 419 | ## Mocking | |
| 372 | 420 | ||
| 373 | 421 | The `node:test` module supports mocking during testing via a top-level `mock` | |
@@ -1201,6 +1249,42 @@ A successful call to [`run()`][] method will return a new {TestsStream} | |||
| 1201 | 1249 | object, streaming a series of events representing the execution of the tests. | |
| 1202 | 1250 | `TestsStream` will emit events, in the order of the tests definition | |
| 1203 | 1251 | ||
| 1252 | + ### Event: `'test:coverage'` | ||
| 1253 | + | ||
| 1254 | + * `data` {Object} | ||
| 1255 | + * `summary` {Object} An object containing the coverage report. | ||
| 1256 | + * `files` {Array} An array of coverage reports for individual files. Each | ||
| 1257 | + report is an object with the following schema: | ||
| 1258 | + * `path` {string} The absolute path of the file. | ||
| 1259 | + * `totalLineCount` {number} The total number of lines. | ||
| 1260 | + * `totalBranchCount` {number} The total number of branches. | ||
| 1261 | + * `totalFunctionCount` {number} The total number of functions. | ||
| 1262 | + * `coveredLineCount` {number} The number of covered lines. | ||
| 1263 | + * `coveredBranchCount` {number} The number of covered branches. | ||
| 1264 | + * `coveredFunctionCount` {number} The number of covered functions. | ||
| 1265 | + * `coveredLinePercent` {number} The percentage of lines covered. | ||
| 1266 | + * `coveredBranchPercent` {number} The percentage of branches covered. | ||
| 1267 | + * `coveredFunctionPercent` {number} The percentage of functions covered. | ||
| 1268 | + * `uncoveredLineNumbers` {Array} An array of integers representing line | ||
| 1269 | + numbers that are uncovered. | ||
| 1270 | + * `totals` {Object} An object containing a summary of coverage for all | ||
| 1271 | + files. | ||
| 1272 | + * `totalLineCount` {number} The total number of lines. | ||
| 1273 | + * `totalBranchCount` {number} The total number of branches. | ||
| 1274 | + * `totalFunctionCount` {number} The total number of functions. | ||
| 1275 | + * `coveredLineCount` {number} The number of covered lines. | ||
| 1276 | + * `coveredBranchCount` {number} The number of covered branches. | ||
| 1277 | + * `coveredFunctionCount` {number} The number of covered functions. | ||
| 1278 | + * `coveredLinePercent` {number} The percentage of lines covered. | ||
| 1279 | + * `coveredBranchPercent` {number} The percentage of branches covered. | ||
| 1280 | + * `coveredFunctionPercent` {number} The percentage of functions covered. | ||
| 1281 | + * `workingDirectory` {string} The working directory when code coverage | ||
| 1282 | + began. This is useful for displaying relative path names in case the tests | ||
| 1283 | + changed the working directory of the Node.js process. | ||
| 1284 | + * `nesting` {number} The nesting level of the test. | ||
| 1285 | + | ||
| 1286 | + Emitted when code coverage is enabled and all tests have completed. | ||
| 1287 | + | ||
| 1204 | 1288 | ### Event: `'test:diagnostic'` | |
| 1205 | 1289 | ||
| 1206 | 1290 | * `data` {Object} | |
@@ -1550,6 +1634,7 @@ added: v18.7.0 | |||
| 1550 | 1634 | aborted. | |
| 1551 | 1635 | ||
| 1552 | 1636 | [TAP]: https://testanything.org/ | |
| 1637 | + [`--test-coverage`]: cli.md#--test-coverage | ||
| 1553 | 1638 | [`--test-name-pattern`]: cli.md#--test-name-pattern | |
| 1554 | 1639 | [`--test-only`]: cli.md#--test-only | |
| 1555 | 1640 | [`--test-reporter-destination`]: cli.md#--test-reporter-destination | |
@@ -1558,6 +1643,7 @@ added: v18.7.0 | |||
| 1558 | 1643 | [`MockFunctionContext`]: #class-mockfunctioncontext | |
| 1559 | 1644 | [`MockTracker.method`]: #mockmethodobject-methodname-implementation-options | |
| 1560 | 1645 | [`MockTracker`]: #class-mocktracker | |
| 1646 | + [`NODE_V8_COVERAGE`]: cli.md#node_v8_coveragedir | ||
| 1561 | 1647 | [`SuiteContext`]: #class-suitecontext | |
| 1562 | 1648 | [`TestContext`]: #class-testcontext | |
| 1563 | 1649 | [`context.diagnostic`]: #contextdiagnosticmessage | |
@@ -1568,4 +1654,5 @@ added: v18.7.0 | |||
| 1568 | 1654 | [describe options]: #describename-options-fn | |
| 1569 | 1655 | [it options]: #testname-options-fn | |
| 1570 | 1656 | [stream.compose]: stream.md#streamcomposestreams | |
| 1657 | + [test reporters]: #test-reporters | ||
| 1571 | 1658 | [test runner execution model]: #test-runner-execution-model | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -391,6 +391,9 @@ Specify the minimum allocation from the OpenSSL secure heap. The default is 2. T | |||
| 391 | 391 | .It Fl -test | |
| 392 | 392 | Starts the Node.js command line test runner. | |
| 393 | 393 | . | |
| 394 | + .It Fl -test-coverage | ||
| 395 | + Enable code coverage in the test runner. | ||
| 396 | + . | ||
| 394 | 397 | .It Fl -test-name-pattern | |
| 395 | 398 | A regular expression that configures the test runner to only execute tests | |
| 396 | 399 | whose name matches the provided pattern. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,7 @@ const { reconnectZeroFillToggle } = require('internal/buffer'); | |||
| 20 | 20 | const { | |
| 21 | 21 | defineOperation, | |
| 22 | 22 | exposeInterface, | |
| 23 | + setupCoverageHooks, | ||
| 23 | 24 | } = require('internal/util'); | |
| 24 | 25 | ||
| 25 | 26 | const { | |
@@ -63,15 +64,7 @@ function prepareExecution(options) { | |||
| 63 | 64 | setupFetch(); | |
| 64 | 65 | setupWebCrypto(); | |
| 65 | 66 | setupCustomEvent(); | |
| 66 | - | ||
| 67 | - // Resolve the coverage directory to an absolute path, and | ||
| 68 | - // overwrite process.env so that the original path gets passed | ||
| 69 | - // to child processes even when they switch cwd. | ||
| 70 | - if (process.env.NODE_V8_COVERAGE) { | ||
| 71 | - process.env.NODE_V8_COVERAGE = | ||
| 72 | - setupCoverageHooks(process.env.NODE_V8_COVERAGE); | ||
| 73 | - } | ||
| 74 | - | ||
| 67 | + setupCodeCoverage(); | ||
| 75 | 68 | setupDebugEnv(); | |
| 76 | 69 | // Process initial diagnostic reporting configuration, if present. | |
| 77 | 70 | initializeReport(); | |
@@ -288,6 +281,17 @@ function setupWebCrypto() { | |||
| 288 | 281 | } | |
| 289 | 282 | } | |
| 290 | 283 | ||
| 284 | + function setupCodeCoverage() { | ||
| 285 | + // Resolve the coverage directory to an absolute path, and | ||
| 286 | + // overwrite process.env so that the original path gets passed | ||
| 287 | + // to child processes even when they switch cwd. Don't do anything if the | ||
| 288 | + // --test-coverage flag is present, as the test runner will handle coverage. | ||
| 289 | + if (process.env.NODE_V8_COVERAGE && !getOptionValue('--test-coverage')) { | ||
| 290 | + process.env.NODE_V8_COVERAGE = | ||
| 291 | + setupCoverageHooks(process.env.NODE_V8_COVERAGE); | ||
| 292 | + } | ||
| 293 | + } | ||
| 294 | + | ||
| 291 | 295 | // TODO(daeyeon): move this to internal/bootstrap/browser when the CLI flag is | |
| 292 | 296 | // removed. | |
| 293 | 297 | function setupCustomEvent() { | |
@@ -299,27 +303,6 @@ function setupCustomEvent() { | |||
| 299 | 303 | exposeInterface(globalThis, 'CustomEvent', CustomEvent); | |
| 300 | 304 | } | |
| 301 | 305 | ||
| 302 | - // Setup User-facing NODE_V8_COVERAGE environment variable that writes | ||
| 303 | - // ScriptCoverage to a specified file. | ||
| 304 | - function setupCoverageHooks(dir) { | ||
| 305 | - const cwd = require('internal/process/execution').tryGetCwd(); | ||
| 306 | - const { resolve } = require('path'); | ||
| 307 | - const coverageDirectory = resolve(cwd, dir); | ||
| 308 | - const { sourceMapCacheToObject } = | ||
| 309 | - require('internal/source_map/source_map_cache'); | ||
| 310 | - | ||
| 311 | - if (process.features.inspector) { | ||
| 312 | - internalBinding('profiler').setCoverageDirectory(coverageDirectory); | ||
| 313 | - internalBinding('profiler').setSourceMapCacheGetter(sourceMapCacheToObject); | ||
| 314 | - } else { | ||
| 315 | - process.emitWarning('The inspector is disabled, ' + | ||
| 316 | - 'coverage could not be collected', | ||
| 317 | - 'Warning'); | ||
| 318 | - return ''; | ||
| 319 | - } | ||
| 320 | - return coverageDirectory; | ||
| 321 | - } | ||
| 322 | - | ||
| 323 | 306 | function setupStacktracePrinterOnSigint() { | |
| 324 | 307 | if (!getOptionValue('--trace-sigint')) { | |
| 325 | 308 | return; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments