Skip to content

test: migrate unit tests from Karma to Vitest#66

Merged
Helias merged 1 commit into
masterfrom
chore/migrate-karma-to-vitest
Jun 20, 2026
Merged

test: migrate unit tests from Karma to Vitest#66
Helias merged 1 commit into
masterfrom
chore/migrate-karma-to-vitest

Conversation

@Helias

@Helias Helias commented Jun 20, 2026

Copy link
Copy Markdown
Member

What

Migrates the unit test setup from Karma + Jasmine to Angular's first-party experimental Vitest runner (@angular/build:unit-test), running in jsdom.

Why

Karma is deprecated and is no longer the default test runner in modern Angular. Vitest is faster, has no browser/ChromeHeadless dependency in CI, and is the path Angular is steering projects toward.

Changes

  • angular.json: test target now uses @angular/build:unit-test with runner: vitest. Build/serve/extract-i18n switched to the @angular/build:* builders, which the unit-test builder needs for correct test-environment wiring.
  • Zone setup: build polyfills now lists the zone.js package entry so the runner statically imports zone.js/testing instead of emitting a top-level await import() that the test build rejects. src/polyfills.ts and src/test.ts are removed (the builder provides the TestBed init).
  • Specs: the legacy waitForAsync(() => …) wrapper in beforeEach is replaced with plain async/await on compileComponents(). zone.js does not patch Vitest, so there is no per-test ProxyZone; this is also the modern recommended pattern. No fakeAsync/tick is used anywhere.
  • rxjs 6 → 7: rxjs 6 lacks ESM exports and breaks Vitest's resolver (rxjs/operators directory import). Angular 22 requires rxjs 7 regardless, so this also fixes a latent mismatch.
  • tsconfig.spec.json: types set to vitest/globals; typeRoots widened so they resolve outside @types (the base config restricts typeRoots to node_modules/@types).
  • package.json: drops karma/jasmine/istanbul dev deps, adds vitest and jsdom.
  • CI: npx ng test --watch=false (dropped --browsers=ChromeHeadless; the runner uses jsdom).

Verification

npx ng test --watch=false → 2 files, 4 tests passing. npx ng build --configuration production succeeds.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Dependencies

    • Upgraded RxJS to version 7.8.2 for improved performance and compatibility.
  • Chores

    • Migrated testing infrastructure to modern tooling for faster and more efficient test execution.
    • Updated Angular build configuration to latest builders for improved build performance.

Replace the Karma/Jasmine unit-test stack with Angular's first-party
Vitest runner (@angular/build:unit-test).

- Switch build/serve/extract-i18n to the @angular/build:* builders, which
  the unit-test builder requires for correct test-environment wiring.
- Use the 'zone.js' polyfill package entry so the runner statically imports
  'zone.js/testing' (avoids an unsupported top-level await in the test build).
- Replace the legacy waitForAsync() beforeEach wrapper with async/await;
  zone.js does not patch Vitest, so there is no per-test ProxyZone.
- Bump rxjs to 7.x: rxjs 6 lacks ESM exports and breaks Vitest resolution,
  and Angular 22 requires rxjs 7 anyway.
- Point tsconfig.spec types at vitest/globals and widen typeRoots so they
  resolve outside @types.
- Drop --browsers=ChromeHeadless from CI; the runner uses jsdom by default.

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

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The project's test stack is migrated from Karma/Jasmine to Vitest. All Angular builders are updated from @angular-devkit/build-angular:* to @angular/build:*. Karma-specific files (karma.conf.js, src/test.ts, src/polyfills.ts) are removed, spec files switch from waitForAsync to native async/await, TypeScript configs adopt Vitest globals, and the CI command drops the explicit --browsers=ChromeHeadless flag.

Changes

Karma → Vitest Migration

Layer / File(s) Summary
Dependency swap
package.json
Removes @types/jasmine, Karma/Istanbul devDependencies; adds vitest and jsdom; upgrades rxjs from 6.6.7 to 7.8.2.
Builder and TypeScript config
angular.json, tsconfig.app.json, tsconfig.spec.json
Switches all builders to @angular/build:*; replaces src/polyfills.ts with zone.js in polyfills; replaces the Karma test target with @angular/build:unit-test using runner: "vitest"; drops src/polyfills.ts from tsconfig.app.json files list; replaces jasmine types with vitest/globals in tsconfig.spec.json.
Spec files and CI
src/app/app.component.spec.ts, src/app/app.service.spec.ts, .github/workflows/tests.yml
Replaces waitForAsync-wrapped beforeEach with native async/await in both spec files; removes --browsers=ChromeHeadless from the CI test command.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 Hop, hop, the Karma's gone away,
No browser to spin up today!
Vitest leaps in, swift and bright,
async/await makes the tests feel right.
Zone.js polyfills, neat and trim —
The bunny grins at every vim. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test: migrate unit tests from Karma to Vitest' directly and accurately reflects the main objective of the changeset—migrating the testing infrastructure from Karma to Vitest.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/migrate-karma-to-vitest

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
package.json (1)

38-40: These deprecated tooling dependencies are still actively used and cannot be safely removed without broader refactoring.

protractor is actively configured in angular.json (builder) and referenced in e2e test files (e2e/src/app.po.ts, e2e/src/app.e2e-spec.ts). tslint has a configuration file in place and codelyzer is referenced within it. Removing them from package.json now would break the e2e test setup and linting. Consider removing these as part of a larger migration effort (e.g., migrating e2e tests away from protractor and switching to ESLint), but not in isolation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 38 - 40, The deprecated packages protractor,
ts-node, and tslint are still actively used in the project and should not be
removed from package.json in isolation. Keep these dependencies in place as they
are actively referenced in angular.json builder configuration and e2e test files
(e2e/src/app.po.ts and e2e/src/app.e2e-spec.ts), and tslint is still configured
for linting. Plan to remove these packages only as part of a larger migration
effort that includes migrating e2e tests away from protractor, updating the
angular.json builder configuration, and switching from tslint to ESLint for
linting.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@package.json`:
- Around line 38-40: The deprecated packages protractor, ts-node, and tslint are
still actively used in the project and should not be removed from package.json
in isolation. Keep these dependencies in place as they are actively referenced
in angular.json builder configuration and e2e test files (e2e/src/app.po.ts and
e2e/src/app.e2e-spec.ts), and tslint is still configured for linting. Plan to
remove these packages only as part of a larger migration effort that includes
migrating e2e tests away from protractor, updating the angular.json builder
configuration, and switching from tslint to ESLint for linting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3a5be516-2e9e-4511-867e-3a456d0b927e

📥 Commits

Reviewing files that changed from the base of the PR and between aa77799 and a2d1db1.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • .github/workflows/tests.yml
  • angular.json
  • karma.conf.js
  • package.json
  • src/app/app.component.spec.ts
  • src/app/app.service.spec.ts
  • src/polyfills.ts
  • src/test.ts
  • tsconfig.app.json
  • tsconfig.spec.json
💤 Files with no reviewable changes (3)
  • src/polyfills.ts
  • src/test.ts
  • karma.conf.js

@Helias Helias merged commit 21d971e into master Jun 20, 2026
3 checks passed
@Helias Helias deleted the chore/migrate-karma-to-vitest branch June 20, 2026 14:00
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