SvelteKit testing with Vitest

When looking to write some tests for my new SvelteKit project I first turned to my old standby Jest. But it turns out that Vitest is a better alternative.

Posted by Tejus Parikh on October 29, 2023

I’ve been toying around with a little side project to learn Svelte. I feel like I’ve been getting a good handle on the basics of the framework and I’ll write more about my impressions in a future post. What I want to talk about here is setting up a unit testing framework.

I initially skipped this step with a plan to add Jest later. I’ve used and liked Jest in the past with React projects and I’m not interested in learning a new testing framework at this time. They seem to be mostly the same, until their not, and the muscle memory starts throwing you off.

There isn’t an official Jest plugin for SvelteKit applications so my journey started with a Google search. (Remember tejusparikh.com is a chatGPT free zone!) After installing Babel, Jest, and other required plugins, I was able to successfully test one of my TS files. However I ran into multiple issues getting svelte-testing-library tests to work. In the process of researching the fixes, I learned what I was doing was less than optimal and I should rethink my approach.

Why Jest is not the best solution for testing in Sveltekit

SvelteKit uses Vite to handle all the front-end tooling to get Svelte and Typescript code into runnable Javascript. None of these are “native” languages for the runtime, so there has to be some translation before the code actually runs. By installing Babel and its toolchain, I was creating a second, completely distinct, build pipeline for my code. Configured correctly the outputs should be the same, but clearly I had not done this and I was getting errors. Also, conceptually, I like the idea that the code I’m testing gets translated by the same toolchain as the code I run.

I decided that learning an additional testing framework is better than a wonky build setup and decided to give Vitest a whirl. Afterall, it has a nicely named helper function vi. If it was emacstest, I might have stuck with Jest a little longer.

Enter Vitest

Vitest is the native testing framework for Vite. Since I was already down the path of blogs, I started there to try and add it to my project. I’ve found that a lot of official documentation assumes that nothing has been written yet and leave out crucial integration steps. This also turned out to be a mistake as the Svelte Testing Library docs had everything that I needed to start testing.

So the most important takeaway of this post: Skip the blogs, just use the Svelte Testing Library docs to get started.

Once installed I was pleasantly surprised to find that my muscle memory for Jest carried over. Chai matchers and Jest matchers are similar enough and the Vitest team has made their mocking library Jest-like.

The test runner is also really nice. It watches by default and automatically runs the test file under active development. It also keeps the console clean without a lot of extraneous content. I don’t recall having this nice of an experience the last time I used a test watcher.

A few useful Vitest tidbits

When testing Svelte code, extending the matchers is very useful. This can be done with an import.

import 'vitest-dom/extend-expect';

This gives matches like toBeInDocument and toBeVisible.

I also felt it took a little investigation to get typescript to not complain about calling functions like mockReturnValue. Wrapping the mock like the following fixes that:

vi.mock(mockedFunction).mockReturnValue(value)

Overall its been a positive experience and I haven’t experienced the small annoyances that often accompany trying to adopt a new testing approach. The creators seem to have thought a lot about dev experience and worked to incorporate the defacto standards to make adoption easy.

Original image is CC-licensed [original source]

Tejus Parikh

I'm a software engineer that writes occasionally about building software, software culture, and tech adjacent hobbies. If you want to get in touch, send me an email at [my_first_name]@tejusparikh.com.