I just completed migrating the unit tests of 40+ code repositories that power the Angular certification program to Vitest. In this post, I’m going to share what I learned in the process. I followed the official instructions to install Vitest and configure angular.json accordingly, then fixed what had to be fixed.
1. Vitest has 99% the same syntax as Jasmine / Jest
It’s interesting how JavaScript testing libraries have pretty much the same syntax and setup, making it tricky to choose one over the other, since they all look the same. For instance, could you guess what this unit test is written for? Is it Jasmine, Jest, or Vitest?
it('should create', () => {
expect(component).toBeTruthy();
});it('should display four tabs', () => {
const tabs = fixture.debugElement.queryAll(By.css(`button`));
expect(tabs.length).toBe(4);
});
The answer is: All of the above! That syntax works for Jasmine, Jest, Vitest, and probably others, too.
For the minor differences, we have…
2. Automated Angular CLI migration
The few differences lie in how mocking and running (or ignoring) specific tests and specs are handled.
Get Alain Chautard’s stories in your inbox
Join Medium for free to get updates from this writer.
Here is a list of these small differences:
fitandfdescribebecomeit.onlyanddescribe.onlyxitandxdescribebecomeit.skipanddescribe.skipspyOncalls becomevi.spyOnjasmine.objectContainingbecomesexpect.objectContainingjasmine.anybecomesexpect.anyjasmine.createSpybecomesvi.fnfail()becomesvi.fail()
Fortunately for us, the Angular CLI has a command to automate these renamings:
ng g @schematics/angular:refactor-jasmine-vitest
3. Async tests are different
If you have unit tests that use RxJs Observables or other async code, such as that one:
it("should return all movies by default", (done) => {
service.filterMovieList().subscribe(movies => {
expect(movies.length).toBe(2);
done();
});
})
The syntax with Vitest has to change, and the CLI automation won’t handle it. With Vitest, we can start fake timers, then run them all and check our expected results. This gives us the following translated test for Vitest:
it("should return all movies by default", async () => {
vi.useFakeTimers();
let moviesReceived = [];
service.filterMovieList().subscribe(movies => moviesReceived = movies);
await vi.runAllTimersAsync();
expect(moviesReceived.length).toBe(2);
})
As with all things async, there are different options, but the above doesn’t seem too complex, so I stuck with that.
4. Browser testing
The main argument for the Angular team to choose Vitest over Jest and other contenders was that it can run tests in a browser, just like Jasmine/Karma.
As a result, after setting things up, I was surprised to see my Vitest tests run without opening a browser! It’s actually an option in Vitest that can be configured as explained here. The feature is useful when testing code that uses actual browser features (local storage, window, etc.)
5. Component testing vs. unit tests
This might be the best part of using Vitest for our tests. Most people find component unit testing in Angular to be overly verbose and complex.
That is, unless we operate at a slightly higher level and start doing component testing instead of unit testing. What I mean by this is instantiating a component in the DOM and then checking it with an API similar to what end-to-end testers are familiar with (in a Cypress/Playwright style)
Here is an example from the Testronaut documentation, a library the uses uses Vitest and Playwright to implement component testing with Angular:
test('should render clear basket button', async ({ page, mount }) => {
await mount(Basket);
await expect(page.getByRole('button', { name: 'Clear' })).toBeVisible();
});
Vitest and Playwright also offer experimental solutions for component testing, which means we have several options right now, so it’s a good space to watch and see if one of these options emerges as the official recommendation, or even becomes part of the Angular testing framework.
My name is Alain Chautard. I am a Google Developer Expert in Angular and a consultant and trainer at Angular Training, where I help web development teams learn and become proficient with Angular / React / JavaScript.
If you need any help learning web technologies, feel free to get in touch!
If you enjoyed this article, please clap for it or share it. Your help is always appreciated. You can also subscribe to my articles and Weekly Angular Newsletter to receive helpful weekly tips and updates about Angular.

