How to Set Up Jest in a SvelteKit App

Box of tools on a wooden table

SvelteKit provides you with all sorts of tools to build a web application. One thing it does not provide, however, is a test runner. There are many JavaScript test runners out there, but one of the most popular is Jest. There are a few potential snags you might encounter when using Jest with SvelteKit, like transforming .svelte files or SvelteKit path aliases. Use this guide to get your test up and running smoothly.

Install Packages

Our first step will be to install all the necessary npm packages.

npm install --save-dev jest babel-jest svelte-jester @babel/preset-env @testing-library/jest-dom @testing-library/svelte @testing-library/user-event

  • jest - Our test framework and runner
  • babel-jest - Transforms our .js files with Babel when running tests
  • @babel/preset-env - Provides a preset list of syntax transforms so we don’t have to manually configure them
  • svelte-jester - Transforms our .svelte files when running tests
  • @testing-library/jest-dom - Provides custom matchers for more concise test when dealing with the DOM
  • @testing-library/svelte - Provides testing utilities for Svelte components
  • @testing-library/user-event - Provides testing utilities for firing DOM events

Configuration

Once all the packages are installed, we need to configure Jest.

Run node_modules/.bin/jest --init and answer the questions it asks as follows:

  • Would you like to use Jest when running “test” script in “package.json”? yes
  • Would you like to use Typescript for the configuration file? no
  • Choose the test environment that will be used for testing jsdom (browser-like)
  • Do you want Jest to add coverage reports? yes
  • Which provider should be used to instrument code for coverage? babel
  • Automatically clear mock calls and instances between every test? no

This will generate a jest.config.mjs file. Next make the following modifications to that file:

  • Setup transforms for .js and .svelte files.
  transform: {
    "^.+\\.js$": "babel-jest",
    "^.+\\.svelte$": ["svelte-jester", { preprocess: true }],
  },
  • Configure support for SvelteKit path aliases. By default SvelteKit just has a $lib alias setup. If you add more of these to your svelte.config.js file, you’ll need to configure them here as well, so that Jest can resolve your imports.
  moduleNameMapper: {
    "^\\$lib/(.*)": "<rootDir>/src/lib/$1",
  },
  • Set a setup file to include common test setup code.
  setupFilesAfterEnv: ["<rootDir>/jest-setup.js"],

After that is done, you will need to create the jest-setup.js mentioned above. This will contain just a single line, and it will save us from having to include that code in all our tests.

import "@testing-library/jest-dom";

Next, we need to configure Babel so it knows how to transform our .js files. Create a file named .babelrc and put the following in it:

{
  "presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]
}

Finally, because we enabled test coverage reports from Jest, we’ll want to tell Git to ignore them by adding the following to our .gitignore:

/coverage

Sample Test

Now with all that set up, we are ready to write tests! Here is an extremely contrived button component located at src/lib/Button.svelte:

<button on:click>Click me</button>

We can test this component with the following code in src/lib/Button.test.js:

import { render, screen } from "@testing-library/svelte";
import userEvent from "@testing-library/user-event";
import Button from "./Button.svelte";

test("renders a button", async () => {
  render(Button);

  expect(screen.getByRole("button")).toHaveTextContent("Click me");
});

test("triggers an event when clicked", () => {
  const { component } = render(Button);
  const callback = jest.fn();
  component.$on("click", callback);

  userEvent.click(screen.getByRole("button"));

  expect(callback).toHaveBeenCalled();
});

You can run npm test and see that everything works as expected!

ESLint

As a bonus, we can set up some ESLint rules for our tests. These rules will enforce many of the best practices the Kent C. Dodds detailed in a blog post. The post is about React, but the points still apply to our Svelte tests.

Install the necessary npm install --save-dev eslint-plugin-jest eslint-plugin-jest-dom eslint-plugin-testing-library

After that make the following modifications to your .eslintrc.cjs file:

  extends: [
    "eslint:recommended",
    "plugin:jest/recommended",
    "plugin:jest-dom/recommended",
    "plugin:testing-library/dom",
    "prettier",
  ],
  plugins: ["jest", "jest-dom", "svelte3", "testing-library"],
  env: {
    browser: true,
    es2017: true,
    node: true,
    "jest/globals": true,
  },
  rules: {
    "testing-library/prefer-user-event": "error",
  },

DockYard is a digital product consultancy specializing in production-ready apps that scale wonderfully as companies grow. We offer a range of consulting services with capabilities in product design, full-stack engineering, project management, QA, strategy, training, and user experience (UX). For over a decade, DockYard has solved complex product challenges for visionary companies like Netflix, Apple, Nasdaq, and Harvard. We’re also dedicated to advancing open-source web development technologies, such as libraries and tooling built around the Elixir programming language. From idea to impact, DockYard empowers forward-thinking teams to build for the future.

Newsletter

Stay in the Know

Get the latest news and insights on Elixir, Phoenix, machine learning, product strategy, and more—delivered straight to your inbox.

Narwin holding a press release sheet while opening the DockYard brand kit box