| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent e8c3db1 commit d03d968
17 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1237,6 +1237,23 @@ Enable module mocking in the test runner. | |||
| 1237 | 1237 | ||
| 1238 | 1238 | This feature requires `--allow-worker` if used with the [Permission Model][]. | |
| 1239 | 1239 | ||
| 1240 | + ### `--experimental-test-tag-filter=<tag>` | ||
| 1241 | + | ||
| 1242 | + <!-- YAML | ||
| 1243 | + added: REPLACEME | ||
| 1244 | + --> | ||
| 1245 | + | ||
| 1246 | + > Stability: 1.0 - Early development | ||
| 1247 | + | ||
| 1248 | + Run only tests whose tag set contains `<tag>`. Tests declare tags via the | ||
| 1249 | + `tags` option on `test()`, `it()`, `suite()`, or `describe()`; tags | ||
| 1250 | + inherit from suites to nested tests by union. Filtering is | ||
| 1251 | + case-insensitive. | ||
| 1252 | + | ||
| 1253 | + The flag may be specified more than once; tests must contain **every** | ||
| 1254 | + filter value to run. See [Test tags][] for details on declaring and | ||
| 1255 | + inheriting tags. | ||
| 1256 | + | ||
| 1240 | 1257 | ### `--experimental-transform-types` | |
| 1241 | 1258 | ||
| 1242 | 1259 | <!-- YAML | |
@@ -4140,6 +4157,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12 | |||
| 4140 | 4157 | [ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage | |
| 4141 | 4158 | [ShadowRealm]: https://github.com/tc39/proposal-shadowrealm | |
| 4142 | 4159 | [Source Map]: https://tc39.es/ecma426/ | |
| 4160 | + [Test tags]: test.md#test-tags | ||
| 4143 | 4161 | [TypeScript type-stripping]: typescript.md#type-stripping | |
| 4144 | 4162 | [V8 Inspector integration for Node.js]: debugger.md#v8-inspector-integration-for-nodejs | |
| 4145 | 4163 | [V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -478,6 +478,82 @@ Test name patterns do not change the set of files that the test runner executes. | |||
| 478 | 478 | If both `--test-name-pattern` and `--test-skip-pattern` are supplied, | |
| 479 | 479 | tests must satisfy **both** requirements in order to be executed. | |
| 480 | 480 | ||
| 481 | + ## Test tags | ||
| 482 | + | ||
| 483 | + <!-- YAML | ||
| 484 | + added: REPLACEME | ||
| 485 | + --> | ||
| 486 | + | ||
| 487 | + > Stability: 1.0 - Early development | ||
| 488 | + | ||
| 489 | + Tags annotate tests and suites with arbitrary string labels. The | ||
| 490 | + [`--experimental-test-tag-filter`][] CLI flag (or the `testTagFilters` | ||
| 491 | + option on [`run()`][]) selects tests whose tag set contains every | ||
| 492 | + provided filter value. | ||
| 493 | + | ||
| 494 | + Tags are an alternative to encoding metadata into test names. They are | ||
| 495 | + useful for cross-cutting axes such as subsystem, speed bucket, flakiness, | ||
| 496 | + or environment, where a name pattern would be brittle. | ||
| 497 | + | ||
| 498 | + ### Authoring tagged tests | ||
| 499 | + | ||
| 500 | + Pass a `tags` array on any of `test()`, `it()`, `suite()`, or `describe()`. | ||
| 501 | + Tags inherit from a suite to its child tests by union—a test inside a | ||
| 502 | + suite tagged `['db']` that declares its own `tags: ['integration']` | ||
| 503 | + effectively has both tags. | ||
| 504 | + | ||
| 505 | + ```mjs | ||
| 506 | + import { describe, it } from 'node:test'; | ||
| 507 | + | ||
| 508 | + describe('database', { tags: ['db'] }, () => { | ||
| 509 | + it('reads a row'); // tags: ['db'] | ||
| 510 | + it('writes a row', { tags: ['integration'] }); // tags: ['db', 'integration'] | ||
| 511 | + it('reconnects after disconnect', { tags: ['flaky'] }); // tags: ['db', 'flaky'] | ||
| 512 | + }); | ||
| 513 | + ``` | ||
| 514 | + | ||
| 515 | + ```cjs | ||
| 516 | + const { describe, it } = require('node:test'); | ||
| 517 | + | ||
| 518 | + describe('database', { tags: ['db'] }, () => { | ||
| 519 | + it('reads a row'); // tags: ['db'] | ||
| 520 | + it('writes a row', { tags: ['integration'] }); // tags: ['db', 'integration'] | ||
| 521 | + it('reconnects after disconnect', { tags: ['flaky'] }); // tags: ['db', 'flaky'] | ||
| 522 | + }); | ||
| 523 | + ``` | ||
| 524 | + | ||
| 525 | + Tag values must be non-empty strings. Tags are matched case-insensitively; | ||
| 526 | + the canonical form is lowercase. Duplicates within a single `tags` array | ||
| 527 | + are collapsed on the lowercased form, preserving the first-seen | ||
| 528 | + declaration order. | ||
| 529 | + | ||
| 530 | + Hooks (`before`, `after`, `beforeEach`, `afterEach`) do not declare their | ||
| 531 | + own tags. They run as part of their owning suite, which carries the | ||
| 532 | + suite's tags. | ||
| 533 | + | ||
| 534 | + ### Filtering by tag | ||
| 535 | + | ||
| 536 | + Each [`--experimental-test-tag-filter`][] value is a literal tag name. A | ||
| 537 | + test runs only when its tag set contains that name. The flag may be | ||
| 538 | + specified more than once; tests must match **every** filter to run. The | ||
| 539 | + same applies to the `testTagFilters` array on [`run()`][]. Filters are | ||
| 540 | + case-insensitive and AND'd with [`--test-name-pattern`][], | ||
| 541 | + [`--test-skip-pattern`][], and `.only` filtering. | ||
| 542 | + | ||
| 543 | + Untagged tests are excluded under any non-empty filter, since the filter | ||
| 544 | + requires the tag to be present. | ||
| 545 | + | ||
| 546 | + ### Reading tags from inside a test | ||
| 547 | + | ||
| 548 | + The [`TestContext`][] object exposes the test's tags as a frozen array | ||
| 549 | + through [`context.tags`][], so tests can branch on their own metadata. | ||
| 550 | + | ||
| 551 | + ### Errors | ||
| 552 | + | ||
| 553 | + A tag value that violates the validation rules above throws | ||
| 554 | + `ERR_INVALID_ARG_VALUE` at the registration site, before any test runs. | ||
| 555 | + A non-array `tags` value throws `ERR_INVALID_ARG_TYPE`. | ||
| 556 | + | ||
| 481 | 557 | ## Extraneous asynchronous activity | |
| 482 | 558 | ||
| 483 | 559 | Once a test function finishes executing, the results are reported as quickly | |
@@ -749,6 +825,8 @@ test runner functionality: | |||
| 749 | 825 | ||
| 750 | 826 | * `--test` - Prevented to avoid recursive test execution | |
| 751 | 827 | * `--experimental-test-coverage` - Managed by the test runner | |
| 828 | + * `--experimental-test-tag-filter` - Filter values are validated by the parent | ||
| 829 | + process and re-emitted to child processes | ||
| 752 | 830 | * `--watch` - Watch mode is handled at the parent level | |
| 753 | 831 | * `--experimental-default-config-file` - Config file loading is handled by the parent | |
| 754 | 832 | * `--test-reporter` - Reporting is managed by the parent process | |
@@ -1570,6 +1648,9 @@ added: | |||
| 1570 | 1648 | - v18.9.0 | |
| 1571 | 1649 | - v16.19.0 | |
| 1572 | 1650 | changes: | |
| 1651 | + - version: REPLACEME | ||
| 1652 | + pr-url: https://github.com/nodejs/node/pull/63221 | ||
| 1653 | + description: Added the `testTagFilters` option. | ||
| 1573 | 1654 | - version: v24.14.0 | |
| 1574 | 1655 | pr-url: https://github.com/nodejs/node/pull/61367 | |
| 1575 | 1656 | description: Add the `env` option. | |
@@ -1656,6 +1737,10 @@ changes: | |||
| 1656 | 1737 | For each test that is executed, any corresponding test hooks, such as | |
| 1657 | 1738 | `beforeEach()`, are also run. | |
| 1658 | 1739 | **Default:** `undefined`. | |
| 1740 | + * `testTagFilters` {string|string\[]} A tag name, or an array of tag names, | ||
| 1741 | + used to filter tests by their declared tags. Tests must contain every | ||
| 1742 | + listed tag to run. Equivalent to passing [`--experimental-test-tag-filter`][] | ||
| 1743 | + on the command line. See [Test tags][]. **Default:** `undefined`. | ||
| 1659 | 1744 | * `timeout` {number} A number of milliseconds the test execution will | |
| 1660 | 1745 | fail after. | |
| 1661 | 1746 | If unspecified, subtests inherit this value from their parent. | |
@@ -1799,6 +1884,9 @@ added: | |||
| 1799 | 1884 | - v18.0.0 | |
| 1800 | 1885 | - v16.17.0 | |
| 1801 | 1886 | changes: | |
| 1887 | + - version: REPLACEME | ||
| 1888 | + pr-url: https://github.com/nodejs/node/pull/63221 | ||
| 1889 | + description: Added the `tags` option. | ||
| 1802 | 1890 | - version: | |
| 1803 | 1891 | - v20.2.0 | |
| 1804 | 1892 | - v18.17.0 | |
@@ -1842,6 +1930,10 @@ changes: | |||
| 1842 | 1930 | * `skip` {boolean|string} If truthy, the test is skipped. If a string is | |
| 1843 | 1931 | provided, that string is displayed in the test results as the reason for | |
| 1844 | 1932 | skipping the test. **Default:** `false`. | |
| 1933 | + * `tags` {string\[]} An array of string labels associated with the test. | ||
| 1934 | + Used together with [`--experimental-test-tag-filter`][] to filter which | ||
| 1935 | + tests run. Tags inherit from suites to nested tests by union. See | ||
| 1936 | + [Test tags][]. **Default:** `[]`. | ||
| 1845 | 1937 | * `todo` {boolean|string} If truthy, the test marked as `TODO`. If a string | |
| 1846 | 1938 | is provided, that string is displayed in the test results as the reason why | |
| 1847 | 1939 | the test is `TODO`. **Default:** `false`. | |
@@ -3425,6 +3517,9 @@ Emitted when code coverage is enabled and all tests have completed. | |||
| 3425 | 3517 | `undefined` if the test was run through the REPL. | |
| 3426 | 3518 | * `name` {string} The test name. | |
| 3427 | 3519 | * `nesting` {number} The nesting level of the test. | |
| 3520 | + * `tags` {string\[]} The flattened lowercased tags declared on the test | ||
| 3521 | + and its ancestor suites, in declaration order. Empty for untagged tests. | ||
| 3522 | + See [Test tags][]. | ||
| 3428 | 3523 | * `testId` {number} A numeric identifier for this test instance, unique | |
| 3429 | 3524 | within the test file's process. Consistent across all events for the same | |
| 3430 | 3525 | test instance, enabling reliable correlation in custom reporters. | |
@@ -3448,6 +3543,9 @@ The corresponding declaration ordered events are `'test:pass'` and `'test:fail'` | |||
| 3448 | 3543 | `undefined` if the test was run through the REPL. | |
| 3449 | 3544 | * `name` {string} The test name. | |
| 3450 | 3545 | * `nesting` {number} The nesting level of the test. | |
| 3546 | + * `tags` {string\[]} The flattened lowercased tags declared on the test | ||
| 3547 | + and its ancestor suites, in declaration order. Empty for untagged tests. | ||
| 3548 | + See [Test tags][]. | ||
| 3451 | 3549 | * `testId` {number} A numeric identifier for this test instance, unique | |
| 3452 | 3550 | within the test file's process. Consistent across all events for the same | |
| 3453 | 3551 | test instance, enabling reliable correlation in custom reporters. | |
@@ -3489,6 +3587,9 @@ defined. | |||
| 3489 | 3587 | `undefined` if the test was run through the REPL. | |
| 3490 | 3588 | * `name` {string} The test name. | |
| 3491 | 3589 | * `nesting` {number} The nesting level of the test. | |
| 3590 | + * `tags` {string\[]} The flattened lowercased tags declared on the test | ||
| 3591 | + and its ancestor suites, in declaration order. Empty for untagged tests. | ||
| 3592 | + See [Test tags][]. | ||
| 3492 | 3593 | * `testId` {number} A numeric identifier for this test instance, unique | |
| 3493 | 3594 | within the test file's process. Consistent across all events for the same | |
| 3494 | 3595 | test instance, enabling reliable correlation in custom reporters. | |
@@ -3515,6 +3616,9 @@ Emitted when a test is enqueued for execution. | |||
| 3515 | 3616 | `undefined` if the test was run through the REPL. | |
| 3516 | 3617 | * `name` {string} The test name. | |
| 3517 | 3618 | * `nesting` {number} The nesting level of the test. | |
| 3619 | + * `tags` {string\[]} The flattened lowercased tags declared on the test | ||
| 3620 | + and its ancestor suites, in declaration order. Empty for untagged tests. | ||
| 3621 | + See [Test tags][]. | ||
| 3518 | 3622 | * `testId` {number} A numeric identifier for this test instance, unique | |
| 3519 | 3623 | within the test file's process. Consistent across all events for the same | |
| 3520 | 3624 | test instance, enabling reliable correlation in custom reporters. | |
@@ -3572,6 +3676,9 @@ since the parent runner only knows about file-level tests. When using | |||
| 3572 | 3676 | `undefined` if the test was run through the REPL. | |
| 3573 | 3677 | * `name` {string} The test name. | |
| 3574 | 3678 | * `nesting` {number} The nesting level of the test. | |
| 3679 | + * `tags` {string\[]} The flattened lowercased tags declared on the test | ||
| 3680 | + and its ancestor suites, in declaration order. Empty for untagged tests. | ||
| 3681 | + See [Test tags][]. | ||
| 3575 | 3682 | * `testId` {number} A numeric identifier for this test instance, unique | |
| 3576 | 3683 | within the test file's process. Consistent across all events for the same | |
| 3577 | 3684 | test instance, enabling reliable correlation in custom reporters. | |
@@ -3611,6 +3718,9 @@ defined. | |||
| 3611 | 3718 | `undefined` if the test was run through the REPL. | |
| 3612 | 3719 | * `name` {string} The test name. | |
| 3613 | 3720 | * `nesting` {number} The nesting level of the test. | |
| 3721 | + * `tags` {string\[]} The flattened lowercased tags declared on the test | ||
| 3722 | + and its ancestor suites, in declaration order. Empty for untagged tests. | ||
| 3723 | + See [Test tags][]. | ||
| 3614 | 3724 | * `testId` {number} A numeric identifier for this test instance, unique | |
| 3615 | 3725 | within the test file's process. Consistent across all events for the same | |
| 3616 | 3726 | test instance, enabling reliable correlation in custom reporters. | |
@@ -4114,6 +4224,20 @@ The attempt number of the test. This value is zero-based, so the first attempt i | |||
| 4114 | 4224 | the second attempt is `1`, and so on. This property is useful in conjunction with the | |
| 4115 | 4225 | `--test-rerun-failures` option to determine which attempt the test is currently running. | |
| 4116 | 4226 | ||
| 4227 | + ### `context.tags` | ||
| 4228 | + | ||
| 4229 | + <!-- YAML | ||
| 4230 | + added: REPLACEME | ||
| 4231 | + --> | ||
| 4232 | + | ||
| 4233 | + > Stability: 1.0 - Early development | ||
| 4234 | + | ||
| 4235 | + * Type: {string\[]} | ||
| 4236 | + | ||
| 4237 | + A frozen array of the test's flattened lowercased tags, in declaration | ||
| 4238 | + order, including any tags inherited from ancestor suites. Empty when the | ||
| 4239 | + test has no tags. See [Test tags][]. | ||
| 4240 | + | ||
| 4117 | 4241 | ### `context.workerId` | |
| 4118 | 4242 | ||
| 4119 | 4243 | <!-- YAML | |
@@ -4329,6 +4453,9 @@ added: | |||
| 4329 | 4453 | - v18.0.0 | |
| 4330 | 4454 | - v16.17.0 | |
| 4331 | 4455 | changes: | |
| 4456 | + - version: REPLACEME | ||
| 4457 | + pr-url: https://github.com/nodejs/node/pull/63221 | ||
| 4458 | + description: Added the `tags` option. | ||
| 4332 | 4459 | - version: | |
| 4333 | 4460 | - v18.8.0 | |
| 4334 | 4461 | - v16.18.0 | |
@@ -4359,6 +4486,10 @@ changes: | |||
| 4359 | 4486 | * `skip` {boolean|string} If truthy, the test is skipped. If a string is | |
| 4360 | 4487 | provided, that string is displayed in the test results as the reason for | |
| 4361 | 4488 | skipping the test. **Default:** `false`. | |
| 4489 | + * `tags` {string\[]} An array of string labels associated with the subtest. | ||
| 4490 | + Used together with [`--experimental-test-tag-filter`][] to filter which | ||
| 4491 | + tests run. Tags inherit from the parent test or suite by union. See | ||
| 4492 | + [Test tags][]. **Default:** `[]`. | ||
| 4362 | 4493 | * `todo` {boolean|string} If truthy, the test marked as `TODO`. If a string | |
| 4363 | 4494 | is provided, that string is displayed in the test results as the reason why | |
| 4364 | 4495 | the test is `TODO`. **Default:** `false`. | |
@@ -4507,8 +4638,10 @@ test.describe('my suite', (suite) => { | |||
| 4507 | 4638 | ``` | |
| 4508 | 4639 | ||
| 4509 | 4640 | [TAP]: https://testanything.org/ | |
| 4641 | + [Test tags]: #test-tags | ||
| 4510 | 4642 | [`--experimental-test-coverage`]: cli.md#--experimental-test-coverage | |
| 4511 | 4643 | [`--experimental-test-module-mocks`]: cli.md#--experimental-test-module-mocks | |
| 4644 | + [`--experimental-test-tag-filter`]: cli.md#--experimental-test-tag-filtertag | ||
| 4512 | 4645 | [`--import`]: cli.md#--importmodule | |
| 4513 | 4646 | [`--no-strip-types`]: cli.md#--no-strip-types | |
| 4514 | 4647 | [`--test-concurrency`]: cli.md#--test-concurrency | |
@@ -4534,6 +4667,7 @@ test.describe('my suite', (suite) => { | |||
| 4534 | 4667 | [`assert.throws`]: assert.md#assertthrowsfn-error-message | |
| 4535 | 4668 | [`context.diagnostic`]: #contextdiagnosticmessage | |
| 4536 | 4669 | [`context.skip`]: #contextskipmessage | |
| 4670 | + [`context.tags`]: #contexttags | ||
| 4537 | 4671 | [`context.todo`]: #contexttodomessage | |
| 4538 | 4672 | [`describe()`]: #describename-options-fn | |
| 4539 | 4673 | [`diagnostics_channel`]: diagnostics_channel.md | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -222,6 +222,10 @@ Disable support for loading ECMAScript modules with require(). | |||
| 222 | 222 | .It Fl -no-strip-types | |
| 223 | 223 | Disable type-stripping for TypeScript files. | |
| 224 | 224 | . | |
| 225 | + .It Fl -experimental-test-tag-filter Ar tag | ||
| 226 | + Run only tests whose tag set contains \fItag\fR. May be specified multiple | ||
| 227 | + times; tests must contain every filter to run. | ||
| 228 | + . | ||
| 225 | 229 | .It Fl -experimental-vm-modules | |
| 226 | 230 | Enable experimental ES module support in VM module. | |
| 227 | 231 | . | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,6 +47,7 @@ function createTestTree(rootTestOptions, globalOptions) { | |||
| 47 | 47 | globalOptions.testSkipPatterns; | |
| 48 | 48 | const isFilteringByOnly = (globalOptions.isolation === 'process' || process.env.NODE_TEST_CONTEXT) ? | |
| 49 | 49 | globalOptions.only : true; | |
| 50 | + const isFilteringByTags = globalOptions.testTagFilters != null; | ||
| 50 | 51 | const harness = { | |
| 51 | 52 | __proto__: null, | |
| 52 | 53 | buildPromise: buildPhaseDeferred.promise, | |
@@ -76,6 +77,7 @@ function createTestTree(rootTestOptions, globalOptions) { | |||
| 76 | 77 | previousRuns: null, | |
| 77 | 78 | isFilteringByName, | |
| 78 | 79 | isFilteringByOnly, | |
| 80 | + isFilteringByTags, | ||
| 79 | 81 | async runBootstrap() { | |
| 80 | 82 | if (globalSetupExecuted) { | |
| 81 | 83 | return PromiseResolve(); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments