Skip to content

Testing routing strategies

The module ships integration tests that exercise all four routing strategies against a shared fixture (test/fixtures/strategy).

Commands

bash
# All strategy scenarios (static generate + SSR build per strategy)
pnpm run test:strategies

# Fast unit tests only — no builds, no browser (~1s)
pnpm run test:unit

# Build-heavy integration suites (strategies, generate, production servers)
pnpm run test:integration

# Browser e2e project (shared prebuilt fixtures + isolated specs), via Vitest
pnpm run test:e2e

# Everything (unit + integration + e2e + packages)
pnpm run test

Project layout

ProjectContentsConfig
unitpure unit tests, no Nuxt buildvitest.unit.config.ts
integrationsuites that spawn nuxi build/generate or @nuxt/test-utils setup()vitest.integration.config.ts
e2ebrowser specs (*.spec.ts) against real serversvitest.e2e.config.ts
package projectsone per packages/*packages/*/vitest.config.ts

The unit / integration split has a single source of truth: INTEGRATION_TESTS in test/setup/heavy-tests.ts — the integration config includes that list and the unit config excludes it, so the two can never drift.

What the strategy suites cover

For each strategy (no_prefix, prefix_except_default, prefix, prefix_and_default) there is one file — test/strategies-<strategy>.test.ts — so Vitest, which parallelizes per file, can run all four concurrently. They share one implementation in test/helpers/strategy-suite.ts:

  1. Static generate — runs nuxi generate into an isolated build dir (NUXT_TEST_BUILD_DIR), serves public/, checks locale routes.
  2. SSR build — runs nuxi build, starts the Nitro server, checks the same routes over HTTP.

Generate-only regressions (prerender success, payload files, nested routes) live in test/strategies-generate.test.ts via registerStrategyGenerateTests() (test/helpers/strategy-generate.ts).

Parallelism

Two rules keep build-spawning suites safe to run concurrently:

  • Own build dir per suite and phaseisolatedBuild(fixture, name) points NUXT_TEST_BUILD_DIR at test/fixtures/<fixture>/.nuxt-test/<name>/, so nothing rimrafs or reads another suite's output.
  • OS-assigned ports, handle-based shutdown — take ports from getFreePort() (test/helpers/port.ts, binds port 0) and stop servers with stopChild() (test/helpers/subprocess.ts), which kills the whole process group. Never free a port by killing whatever process owns it (lsof -ti tcp:<port> + SIGKILL): with parallel workers that can kill a sibling suite's server, which surfaces as an unrelated ERR_IPC_CHANNEL_CLOSED crash.

E2E shared fixtures

Browser e2e specs run through Vitest (--project e2e) driving a real Playwright browser against real Nuxt servers — see test/setup/vitest-e2e.ts. Specs without per-spec nuxtConfig connect to prebuilt servers started once by test/setup/vitest-global-setup.ts (build/serve logic in shared-fixtures-core.ts) via setupE2E({ shared: '<fixture>' }). Specs with custom config or dev: true build their own app per file via setupE2E({ rootDir, nuxtConfig }).

See also Testing the module.

Released under the MIT License.