If you’ve worked on Angular projects long enough, you probably know Karma.
It worked for years. But in modern frontend development, slow test startup, browser dependency, and awkward debugging start to feel outdated.
The test framework Vitest becomes official and default for new Angular projects.
Here is what worked and what we learned from migration.
Why move away from Karma?
To have a briefly comparaison between the two frameworks:
| Karma | Vitest |
|---|---|
| Browser-based | Node-based |
| Slower startup | Fast startup |
| Harder debugging | Better DX with |
| Legacy Angular default | Modern ecosystem |
| Weak watch mode | Excellent watch mode |
Installation
If you are using Angular, in the official documentation, we have this article helping to migrate https://angular.dev/guide/testing/migrating-to-vitest
I will not dive into this too much.
Configuration
After installing vitest, jsdom/ happy-dom, this is where your real experience helps. To create your vitest.config.ts
A basic config could be like this:
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
plugins: [tsconfigPaths()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['src/test-setup.ts']
}
});
Some specifique configs example:
test: {
// use the following configs will improve the speed of tests
isolate: false,
pool: 'threads',
css: false,
// Test reporters (for test execution results)
reporters: [
'default',
['junit', { outputFile: path to the file }],
['junit', { outputFile: path to the file }],
],
// Coverage configuration (for code coverage)
coverage: {
provider: 'v8',
reporter: [], // file type can be 'lcov', 'text', 'cobertura'
reportsDirectory: reportsDir,
exclude: [
'./src/test-setup.ts'
]
}
}
Another change is in angular.json file. In addition to the documentation, we can have some other updates:
"test": {
"builder": "@angular/build:unit-test",
"options": {
"runner": "vitest",
"runnerConfig": "vitest.config.ts", // to tell using this config
"coverageReporters": ["html", "lcov"],
"coverage": true,
Refactor code from Karma to Vitest
In the doc, angular CLI provides ng g @schematics/angular:refactor-jasmine-vitest to globally refactor some part of code. But we still, in some cases like fakeAsync, flush or waitForAsync, refactor the code manually even though it covers a lot.
I would share some exemples later in another post.