Skip to content

Commit 660adf7

Browse files
committed
docs: create Vitest migration guide
This commit introduces a new guide for migrating existing Angular projects from Karma/Jasmine to Vitest. The guide covers: - Manual steps for installing dependencies and updating `angular.json`. - Handling custom `karma.conf.js` configurations. - Removing Karma-related files and packages. - Configuring browser mode for Vitest. - Details on the `refactor-jasmine-vitest` schematic for automated test refactoring. The guide also clarifies that while Vitest is the default for new projects, migration for existing projects is experimental. It emphasizes reviewing changes and provides guidance on adapting custom Karma configurations to Vitest. Renames `experimental-unit-test.md` to `migrating-to-vitest.md` and updates `sub-navigation-data.ts` accordingly.
1 parent cc095d4 commit 660adf7

File tree

3 files changed

+222
-85
lines changed

3 files changed

+222
-85
lines changed

adev/src/app/routing/sub-navigation-data.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,9 +573,9 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
573573
contentPath: 'guide/testing/utility-apis',
574574
},
575575
{
576-
label: 'Experimental unit testing integration',
576+
label: 'Migrating from Karma to Vitest',
577577
path: 'guide/testing/unit-tests',
578-
contentPath: 'guide/testing/experimental-unit-test',
578+
contentPath: 'guide/testing/migrating-to-vitest',
579579
},
580580
{
581581
label: 'Component harnesses overview',

adev/src/content/guide/testing/experimental-unit-test.md

Lines changed: 0 additions & 83 deletions
This file was deleted.
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# Migrating from Karma to Vitest
2+
3+
The Angular CLI uses [Vitest](https://vitest.dev/) as the default unit test runner for new projects. This guide provides instructions for migrating an existing project from Karma and Jasmine to Vitest.
4+
5+
IMPORTANT: Migrating an existing project to Vitest is considered experimental. This process also requires the use of the `application` build system, which is the default for all newly created projects.
6+
7+
## Manual migration steps
8+
9+
Before using the automated refactoring schematic, you must manually update your project to use the Vitest test runner.
10+
11+
### 1. Install dependencies
12+
13+
Install `vitest` and a DOM emulation library. While browser testing is still possible (see [step 5](#5-configure-browser-mode-optional)), Vitest uses a DOM emulation library by default to simulate a browser environment within Node.js for faster test execution. The CLI automatically detects and uses `happy-dom` if it's installed; otherwise, it falls back to `jsdom`. You must have one of these packages installed.
14+
15+
<docs-code-multifile>
16+
<docs-code header="pnpm" language="shell">
17+
pnpm add -D vitest jsdom
18+
</docs-code>
19+
<docs-code header="npm" language="shell">
20+
npm install --save-dev vitest jsdom
21+
</docs-code>
22+
<docs-code header="yarn" language="shell">
23+
yarn add --dev vitest jsdom
24+
</docs-code>
25+
</docs-code-multifile>
26+
27+
### 2. Update `angular.json`
28+
29+
In your `angular.json` file, find the `test` target for your project and change the `builder` to `@angular/build:unit-test`.
30+
31+
```json
32+
{
33+
"projects": {
34+
"your-project-name": {
35+
"architect": {
36+
"test": {
37+
"builder": "@angular/build:unit-test"
38+
}
39+
}
40+
}
41+
}
42+
}
43+
```
44+
45+
The `unit-test` builder defaults to `"tsConfig": "tsconfig.spec.json"` and `"buildTarget": "::development"`. You can explicitly set these options if your project requires different values. For example, if the `development` build configuration is missing or you need different options for testing, you can create and use a `testing` or similarly named build configuration for `buildTarget`.
46+
47+
The `@angular/build:karma` builder previously allowed build options (like `polyfills`, `assets`, or `styles`) to be configured directly within the `test` target. The new `@angular/build:unit-test` builder does not support this. If your test-specific build options differ from your existing `development` build configuration, you must move them to a dedicated build target configuration. If your test build options already match your `development` build configuration, no action is needed.
48+
49+
### 3. Handle custom `karma.conf.js` configurations
50+
51+
Custom configurations in `karma.conf.js` are not automatically migrated. Before deleting your `karma.conf.js` file, review it for any custom settings that need to be migrated.
52+
53+
Many Karma options have equivalents in Vitest that can be set in a custom Vitest configuration file (e.g., `vitest.config.ts`) and linked to your `angular.json` via the `runnerConfig` option.
54+
55+
Common migration paths include:
56+
57+
- **Reporters**: Karma reporters must be replaced with Vitest-compatible reporters. These can often be configured directly in your `angular.json` under the `test.options.reporters` property. For more advanced configurations, use a custom `vitest.config.ts` file.
58+
- **Plugins**: Karma plugins may have Vitest equivalents that you will need to find and install. Note that code coverage is a first-class feature in the Angular CLI and can be enabled with `ng test --coverage`.
59+
- **Custom Browser Launchers**: These are replaced by the `browsers` option in `angular.json` and the installation of a browser provider like `@vitest/browser-playwright`.
60+
61+
For other settings, consult the official [Vitest documentation](https://vitest.dev/config/).
62+
63+
### 4. Remove Karma and `test.ts` files
64+
65+
You can now delete `karma.conf.js` and `src/test.ts` from your project and uninstall the Karma-related packages. The following commands are based on the packages installed in a new Angular CLI project; your project may have other Karma-related packages to remove.
66+
67+
<docs-code-multifile>
68+
<docs-code header="pnpm" language="shell">
69+
pnpm remove karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter
70+
</docs-code>
71+
<docs-code header="npm" language="shell">
72+
npm uninstall karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter
73+
</docs-code>
74+
<docs-code header="yarn" language="shell">
75+
yarn remove karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter
76+
</docs-code>
77+
</docs-code-multifile>
78+
79+
### 5. Configure browser mode (optional)
80+
81+
If you need to run tests in a real browser, you must install a browser provider and configure your `angular.json`.
82+
83+
**Install a browser provider:**
84+
85+
Choose one of the following browser providers based on your needs:
86+
87+
- **Playwright**: `@vitest/browser-playwright` for Chromium, Firefox, and WebKit.
88+
- **WebdriverIO**: `@vitest/browser-webdriverio` for Chrome, Firefox, Safari, and Edge.
89+
- **Preview**: `@vitest/browser-preview` for Webcontainer environments (like StackBlitz).
90+
91+
<docs-code-multifile>
92+
<docs-code header="pnpm" language="shell">
93+
pnpm add -D @vitest/browser-playwright
94+
</docs-code>
95+
<docs-code header="npm" language="shell">
96+
npm install --save-dev @vitest/browser-playwright
97+
</docs-code>
98+
<docs-code header="yarn" language="shell">
99+
yarn add --dev @vitest/browser-playwright
100+
</docs-code>
101+
</docs-code-multifile>
102+
103+
**Update `angular.json` for browser mode:**
104+
105+
Add the `browsers` option to your `test` target's options. The browser name depends on the provider you installed (e.g., `chromium` for Playwright, `chrome` for WebdriverIO).
106+
107+
```json
108+
{
109+
"projects": {
110+
"your-project-name": {
111+
"architect": {
112+
"test": {
113+
"builder": "@angular/build:unit-test",
114+
"options": {
115+
"browsers": ["chromium"]
116+
}
117+
}
118+
}
119+
}
120+
}
121+
}
122+
```
123+
124+
Headless mode is enabled automatically if the `CI` environment variable is set or if a browser name includes "Headless" (e.g., `ChromeHeadless`). Otherwise, tests will run in a headed browser.
125+
126+
## Automated test refactoring with schematics
127+
128+
IMPORTANT: The `refactor-jasmine-vitest` schematic is experimental and may not cover all possible test patterns. Always review the changes made by the schematic.
129+
130+
The Angular CLI provides the `refactor-jasmine-vitest` schematic to automatically refactor your Jasmine tests to use Vitest.
131+
132+
### Overview
133+
134+
The schematic automates the following transformations in your test files (`.spec.ts`):
135+
136+
- Converts `fit` and `fdescribe` to `it.only` and `describe.only`.
137+
- Converts `xit` and `xdescribe` to `it.skip` and `describe.skip`.
138+
- Converts `spyOn` calls to the equivalent `vi.spyOn`.
139+
- Replaces `jasmine.objectContaining` with `expect.objectContaining`.
140+
- Replaces `jasmine.any` with `expect.any`.
141+
- Replaces `jasmine.createSpy` with `vi.fn`.
142+
- Updates `beforeAll`, `beforeEach`, `afterAll`, and `afterEach` to their Vitest equivalents.
143+
- Converts `fail()` to Vitest's `vi.fail()`.
144+
- Adjusts expectations to match Vitest APIs
145+
- Adds TODO comments for code that cannot be automatically converted
146+
147+
The schematic **does not** perform the following actions:
148+
149+
- It does not install `vitest` or other related dependencies.
150+
- It does not change your `angular.json` to use the Vitest builder or migrate any build options (like `polyfills` or `styles`) from the `test` target.
151+
- It does not remove `karma.conf.js` or `test.ts` files.
152+
- It does not handle complex or nested spy scenarios, which may require manual refactoring.
153+
154+
### Running the schematic
155+
156+
Once your project is configured for Vitest, you can run the schematic to refactor your test files.
157+
158+
To refactor **all** test files in your default project, run:
159+
160+
```bash
161+
ng g @schematics/angular:refactor-jasmine-vitest
162+
```
163+
164+
### Options
165+
166+
You can use the following options to customize the schematic's behavior:
167+
168+
| Option | Description |
169+
| :---------------------- | :-------------------------------------------------------------------------------------------------- |
170+
| `--project <name>` | Specify the project to refactor in a multi-project workspace. <br> Example: `--project=my-lib` |
171+
| `--include <path>` | Refactor only a specific file or directory. <br> Example: `--include=src/app/app.component.spec.ts` |
172+
| `--fileSuffix <suffix>` | Specify a different file suffix for test files. <br> Example: `--fileSuffix=.test.ts` |
173+
| `--add-imports` | Add explicit `vitest` imports if you have disabled globals in your Vitest configuration. |
174+
| `--verbose` | See detailed logging of all transformations applied. |
175+
176+
### After migrating
177+
178+
After the schematic completes, it's a good practice to:
179+
180+
1. **Run your tests**: Execute `ng test` to ensure that all tests still pass after the refactoring.
181+
2. **Review the changes**: Look over the changes made by the schematic, paying close attention to any complex tests, especially those with intricate spies or mocks, as they may require further manual adjustments.
182+
183+
The `ng test` command builds the application in _watch mode_ and launches the configured runner. Watch mode is enabled by default when using an interactive terminal and not running on CI.
184+
185+
## Configuration
186+
187+
The Angular CLI takes care of the Vitest configuration for you, constructing the full configuration in memory based on options in `angular.json`.
188+
189+
### Custom Vitest configuration
190+
191+
IMPORTANT: While using a custom configuration enables advanced options, the Angular team does not provide direct support for the specific contents of the configuration file or for any third-party plugins used within it. The CLI will also override certain properties (`test.projects`, `test.include`) to ensure proper operation.
192+
193+
You can provide a custom Vitest configuration file to override the default settings. For a full list of available options, see the official [Vitest documentation](https://vitest.dev/config/).
194+
195+
**1. Direct path:**
196+
Provide a direct path to a Vitest configuration file in your `angular.json`:
197+
198+
```json
199+
{
200+
"projects": {
201+
"your-project-name": {
202+
"architect": {
203+
"test": {
204+
"builder": "@angular/build:unit-test",
205+
"options": { "runnerConfig": "vitest.config.ts" }
206+
}
207+
}
208+
}
209+
}
210+
}
211+
```
212+
213+
**2. Automatic search for base configuration:**
214+
If you set `runnerConfig` to `true`, the builder will automatically search for a shared `vitest-base.config.*` file in your project and workspace roots.
215+
216+
## Bug reports
217+
218+
Report issues and feature requests on [GitHub](https://github.com/angular/angular-cli/issues).
219+
220+
Please provide a minimal reproduction where possible to aid the team in addressing issues.

0 commit comments

Comments
 (0)