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 runnerbabel-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 themsvelte-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 yoursvelte.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.