chore: modernize testing infrastructure#5160
Merged
Merged
Conversation
✅ Deploy Preview for ngrx-io ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
ad3b722 to
9c205f5
Compare
markostanimirovic
approved these changes
Jun 9, 2026
brandonroberts
approved these changes
Jun 10, 2026
timdeschryver
approved these changes
Jun 10, 2026
timdeschryver
left a comment
Member
There was a problem hiding this comment.
Looks good to me!
(Sorry for the conflicts)
We can also add to include Analog's snapshot serializers to clean up some html snapshots and to remove the dependency to jest-preset-angular.
- Establish workspace-level root vitest.config.mts config file. - Standardize sub-project configs by renaming *vite.config.mts/ts to vitest.config.mts and merging shared baseConfig. - Exclude schematic and migration test pipelines temporarily to keep CI green. - Add FOLLOW_UP_TASKS.md to document identified migration tasks and technical debt. - Include **/*.test-d.ts in Signals specification tsconfig.
Drop the explicit test configFile and tsconfig path aliases since the workspace tsconfig and vitest config already resolve @ngrx-io imports. Co-authored-by: Cursor <cursoragent@cursor.com>
- modules/effects/vitest.config.mts: Merged imports and timeout config. - modules/effects/migrations/6_0_0/index.spec.ts & modules/entity/migrations/6_0_0/index.spec.ts: Removed redundant top-level collectionPath variable declarations. - modules/effects/testing/spec/mock_actions.spec.ts: Standardized on firstValueFrom + async/await. - projects/www/project.json: Merged dependsOn and removed redundant configFile options. - package.json & pnpm-lock.yaml: Kept shiki v1.29.2 from origin/main and removed unused strip-json-comments dependency.
9fa7f37 to
0750521
Compare
By default, Vitest runs tests in the 'threads' pool (using worker_threads). However, schematics/migrations tests (e.g. using @angular-devkit/schematics and ora) fail with 'SyntaxError: Cannot use import statement outside a module' inside worker threads. This happens because worker threads have strict module loader limitations and do not fully support process-level hooks (like exit listeners) required by these packages. Setting `pool: 'forks'` spawns tests in OS-level child processes (child_process.fork), restoring native Node.js ESM/CJS loader behavior and process API support.
Contributor
Author
|
@markostanimirovic, @timdeschryver, @brandonroberts if you want you can take a look but the conflicts are gone and we are ready to go from my side. |
timdeschryver
approved these changes
Jun 13, 2026
timdeschryver
left a comment
Member
There was a problem hiding this comment.
Thanks @rainerhahnekamp !
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR unifies Vitest into a root workspace, adds native type-test modes (runtime / type-only / combi), and aligns per-project configs. Modules already ran Vitest via
vite.config.mts; this centralizes that setup and enables IDE tooling.What this PR does
/vitest.config.mtsand per-projectvitest.config.mtsfiles (14 config files: 12modules/*,example-app,www)vite.config.mtswithvitest.config.mtsextending sharedbaseConfigviamergeConfig(exceptwww, which keeps a standalone Analog config)pnpm vitest --project <project-name>and Vitest IDE tooling across the monorepo (13 projects in the root workspace — see Projects with customized test config).test-d.ts), and combi (types/*.spec.tswith Vitest type-check)example-app: movestest-setup.tsto the project root and updatestsconfig.spec.json(filespath, dropsstrict: false)dist/modules/...paths (relies on existingdependsOn: ["build"]when running through Nx)mock_actions→async/await, localstrip-json-commentsfor eslint-plugin schematicsThe main file is
/vitest.config.mts. It exposes sharedbaseConfigfor most projects and registers workspace projects undermodules/*andexample-app— the repo root is not a project itself. Each standard project extendsbaseConfigviamergeConfig; exceptions are noted below.Current state
Runtime tests already run through Vitest; type suites are not migrated yet.
types/—ts-snippet(25),expectTypeOf(1), custom helpers (2), runtime regression (1)*.types.spec.ts, 13 plain*.spec.ts; no*.test-d.tsfiles yetstandalone-appis still on Jest; everything else in scope uses VitestThe configuration below is the basis for follow-up PRs that migrate those suites to native type-only or combi tests (see Follow-up tasks).
Projects with customized test config
www: Standalone Analog config (notbaseConfig). Renamedvite.config.ts→vitest.config.mts;project.jsonconfigFileupdated for build/serve. Explicitresolve.aliasfor@ngrx-io(Vitest was resolving to/src/app/...). Not part of the root Vitest workspace. Use Nx:nx run www:test,nx run www:build,nx serve www.effects:include: ['spec/**/*.spec.ts']andtestTimeout: 15000(sameincludeasmain— see Excluded specs).entity:include: ['spec/**/*.spec.ts']andtestTimeout: 15000(sameincludeasmain; timeout raised for slowts-snippetcombi tests on CI).schematics:include: ['src/**/*.spec.ts'](same asmain).eslint-plugin:testTimeout: 8000.Running tests
Nx (CI and recommended):
nx run <project>:testornx affected -t test. Module targets use existingdependsOn: ["build"], sodist/modules/...is populated before schematic and migration specs run.Native Vitest (IDE /
pnpm vitest): The root workspace enablespnpm vitestandpnpm vitest --project <name>for modules andexample-app, but it does not trigger Nx builds. Schematic and migration tests load compiled factories fromdist/modules/...via Noderequire()— the same requirement as onmain. Run a build first:Without that step, schematic/migration specs fail with missing
dist/modules/...modules. Runtime-only specs (e.g. underspec/) are unaffected.For
www, usenx run www:test— it is not registered in the root workspace.Excluded specs (dead on
main)Three modules keep the narrower
includepatterns frommain. These specs exist in the repo but are not executed by Vitest ornx test— they were never part of CI onmaineither:includeeffectsspec/**/*.spec.tsmigrations/**,schematics/ng-add,testing/spec/mock_actionsentityspec/**/*.spec.tsmigrations/6_0_0,schematics/ng-addschematicssrc/**/*.spec.tsmigrations/6_0_09 migration/schematic specs in total (plus
mock_actionsoneffects). Enabling them is a follow-up (see Enable excluded migration and schematic tests).Folder Structure
With Vitest we have three types of tests:
expect, etc. They are not type-safe — Vitest strips types and runs the code. Fast, but no type safety.expectTypeOforassertType. Vitest only runs the compiler on them; they are not executed at runtime.@ts-expect-errorare not precise enough to count as type tests alone. Example:This is a valid type test, but
@ts-expect-errordoes not differentiate between a type-only error and a syntax error. For example, the test would also succeed for:Therefore, these tests need to run both as runtime and type tests.
With the new configuration, combi tests belong in a
types/subfolder. Files matching**/*.test-d.tsrun as type-tests only (anywhere in the project);**/{spec,test}.tsfiles undertypes/run as both runtime and type tests.Test migration patterns
Patterns applied when enabling schematic, migration, and legacy tests under Vitest.
Schematic and migration paths:
__dirname→dist/SchematicTestRunnerloads factories via Noderequire(), which expects compiled.jsfiles. Tests should point at the built output, not source JSON next to.tsfiles.The same applies to schematic collections:
Module
testtargets rely on existingdependsOn: ["build"]sodist/exists when tests run through Nx. That does not apply to nativepnpm vitest(see Running tests). Project apps (example-app,www) have no schematic/migration specs that require a pre-test build.Replacing deprecated
done()callbacksVitest 4 deprecates Jasmine-style
done()in favor ofasync/await:CJS schematic dependencies under Vitest
Schematics compiled to CommonJS cannot
require()ESM-only packages resolved from the workspace root. For@ngrx/eslint-plugin,strip-json-commentswas replaced with a local helper bundled into the schematic output:Slow type-check tests:
testTimeoutType tests that run
tscviats-snippetcan exceed the default timeout. Projects with heavy type suites set a higher limit invitest.config.mts:Combi specs under
spec/types/can exceed 8s on CI even when the type-check pass succeeds.Follow-up tasks
Outstanding work after this PR (verified June 2026). Planned as separate PRs on top of the configuration introduced here.
Enable excluded migration and schematic tests
Planned. Widen
includeineffects,entity, andschematicsto match other modules (**/*.{spec,test}.ts), then ensure those specs pass under Vitest withdependsOn: ["build"](and document the manualnx buildstep for nativepnpm vitest). The 9 currently excluded migration/schematic specs are listed in Excluded specs.Migrate type suites to native Vitest type tests
Planned. Convert the 29 existing
types/spec files fromts-snippet(and related helpers) to native.test-d.tstype-only tests or combi tests. Start with smaller packages, then tackle heavy suites (signals,store,effects). Once complete, drop the customtypecheck.includepattern (**/types/**/*.{spec,test}.ts) invitest.config.mtsand standardize on*.test-d.tsnaming.Refactor deprecated
done()callbacksPlanned.
modules/effects/testing/spec/mock_actions.spec.tsis refactored toasync/awaitbut currently excluded viaeffects'sincludepattern (dead onmain). Vitest 4 still warns on Jasmine-styledone()indata,router-store,store, andstore-devtools(roughly 70 usages across 16 spec files). These should move to Promises orasync/await(see Replacing deprecateddone()callbacks).Fix source type errors (
ignoreSourceErrors)Planned. Shared
baseConfiginvitest.config.mtssetstypecheck.ignoreSourceErrors: trueso Vitest type-checking only reports errors in test files, not in library source. Without it, 17 type errors in source code surface duringpnpm vitest. Fix those errors and removeignoreSourceErrorsfrombaseConfigso type-check runs also guard production code. This does not apply towww, which uses its own standalone config and setsignoreSourceErrorsseparately.Performance: long-running type tests
Partially addressed.
with-entities.types.spec.tsand the rest of thesignalstype suite pass with the default timeout.effects,entity(15s), andeslint-plugin(8s) use raisedtestTimeoutvalues as a stopgap (see Slow type-check tests). Optimization may become less urgent as suites migrate offts-snippet.Remove legacy test framework artifacts
Planned.
jasmine-marblesremains in a fewmodules/specs (store,operators,data), Jasmine/Jest devDependencies remain inpackage.json, andprojects/standalone-appis still on Jest/Karma. Migrate or remove where Vitest (or@analogjs/vitest-angular) equivalents exist.Browser runtime instead of JSDOM
Future. Shared config sets
environment: 'jsdom'. Moving runtime tests to a real browser environment is a larger follow-up for closer DOM fidelity.Does this PR introduce a breaking change?
Native
pnpm vitestdoes not auto-build; schematic/migration tests neednx buildfirst.wwwis not in the root workspace — use Nx forwwwtests and builds. No breaking changes to published packages.