Skip to content

test(node-integration-tests): Run ESM and CJS scenarios concurrently#22086

Draft
mydea wants to merge 4 commits into
developfrom
feat/node-it-parallel-esm-cjs
Draft

test(node-integration-tests): Run ESM and CJS scenarios concurrently#22086
mydea wants to merge 4 commits into
developfrom
feat/node-it-parallel-esm-cjs

Conversation

@mydea

@mydea mydea commented Jul 8, 2026

Copy link
Copy Markdown
Member

Each createRunner scenario runs in its own spawned node child process, so within a suite the runner mostly sits idle waiting on that child. But createEsmAndCjsTests (and the ESM/CJS-only variants) registered their runs with plain test, so the ESM run fully finished before the CJS run even started.

This defaults those runs to test.concurrent, so ESM + CJS (and multiple test cases in a suite) overlap. Big win for local / targeted runs where cores are otherwise idle (a two-mode suite drops from ~sum to ~max of the two runs); in CI it stays bounded by vitest’s maxConcurrency.

Suites that share mutable external state must stay sequential, handled via a new sequential option on CommonTestOptions:

  • Suites with a co-located docker-compose.yml (shared database/broker container) are auto-detected and defaulted to sequential — self-maintaining for future docker suites.
  • Mongo/mysql-style suites sharing a MongoMemoryServer / mock server started in beforeAll have no compose file, so they pass { sequential: true } explicitly (mysql’s mock server is stateless and stays concurrent).

An explicit sequential always wins over the auto-detected default.

Pairs well with (but is independent of) the event-driven completion and compile-cache PRs.

🤖 Generated with Claude Code

`createEsmAndCjsTests` (and the ESM/CJS-only variants) registered their runs
with plain `test`, so the ESM run finished before the CJS run started even
though each spawns its own independent child process and mostly sits idle
waiting on it. Default them to `test.concurrent` so ESM+CJS (and multiple test
cases in a suite) overlap — a big win for local/targeted runs where cores are
otherwise idle, bounded in CI by vitest's `maxConcurrency`.

Suites that share mutable external state must stay sequential:
- Suites with a co-located `docker-compose.yml` (shared DB/broker container) are
  auto-detected and defaulted to sequential — self-maintaining for future ones.
- Mongo/mysql-style suites that share a `MongoMemoryServer`/mock server started
  in `beforeAll` have no compose file, so they pass `{ sequential: true }`.

A new `sequential` option (on `CommonTestOptions`) drives this and always wins
over the auto-detected default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mydea mydea requested a review from a team as a code owner July 8, 2026 12:07
@mydea mydea requested review from JPeer264 and andreiborza and removed request for a team July 8, 2026 12:07
@mydea mydea marked this pull request as draft July 8, 2026 12:27
mydea and others added 3 commits July 8, 2026 14:39
…s sequential

Suites that call `expect.assertions()` / `expect.hasAssertions()` use the
module-global `expect`, whose assertion counter is shared across concurrently
running tests — so under the new `test.concurrent` default, sibling runs
inflated the count and tripped "expected N assertions, but got 2N". The
per-test context `expect` isn't a reliable workaround here because these suites
assert inside I/O callbacks (e.g. mock server handlers) that lose vitest's async
context, so those assertions wouldn't be counted at all.

Detect this the same way as docker-compose suites: read the suite's `test.ts`
and default it to sequential when it uses assertion counting. Self-maintaining —
future suites are covered without per-suite opt-outs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f292a5b. Configure here.

createEsmAndCjsTests(__dirname, 'scenario with space.mjs', 'instrument.mjs', (createRunner, test, mode) => {
test('reads encoded context lines from filenames with spaces', async () => {
expect.assertions(1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global expect with concurrent tests

Medium Severity

This suite registers tests through createEsmAndCjsTests, which now uses test.concurrent by default, but the callback still uses the module-level expect import inside matchers. Vitest requires the test-scoped expect from the test context for concurrent tests; other suites in the same PR were updated to async ({ expect }) => for that reason.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit f292a5b. Configure here.

createCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
test('ignores user from request', async () => {
expect.assertions(2);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global expect with concurrent tests

Medium Severity

createCjsTests now passes test.concurrent into this callback, so the two cases can overlap, yet both still assert with the imported expect in the event callback. That bypasses Vitest’s concurrent test context and matches the same gap fixed elsewhere in this PR with async ({ expect }) =>.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit f292a5b. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant