An Overall Look at Unit Testing Svelte Components

Ryan Tan
Level Up Coding
Published in
4 min readJun 26, 2022

--

On top is a header that says Unit Testing Svelte Components. Below is a clip art of a beaker, and 2 flasks, followed by an arrow pointing to a button that says “Help”.

Unit tests can prove to be very useful if you’re managing a league of components for your project(s). If you want to make sure that the components still function properly after future changes, it is recommended to do unit testing after every change.

Getting Started — Initial Set Up

We will be using Jest as well as the Testing Library libraries to test our components.

Install jest, @testing-library/jest-dom, @testing-library/svelte to your project’s devDependencies.

Let’s create a testing file for your component. Let’s say we have a Text Input component Input that takes in the attributes id, class, and type .

To test the component, create a __test__ folder for it. Jest will look for files that have .test.js or .spec.js at the end of the filename.

This is how I structure such files:

Imports

import { render, fireEvent } from '@testing-library/svelte';
import Component from "../src/Component.svelte";
import SlotTest from "../../../test/slot/SlotTest.svelte";

Usually you would need to import the render and fireEvent functions from @testing-library , the component itself, and a component to test slots ( SlotTest ).

Let’s go through what render and fireEvent does:

render — Getting the component

const result = render(Component, { props });

The render function basically renders the component onto a document body with the specified props.

After that, I would get the element itself using result.container like so:

const { container } = result;
// OR
const { container } = render(Component, { props };

Then, get the element itself using a selector:

const component = container.getElementsByClassName(props.class)[0];

It is recommended to use a narrower get method if you know what you’re searching for. If not, you may use querySelector or querySelectorAll , however these functions are not very efficient, and may need some resources as they search the whole document.

fireEvent — Testing Events

await fireEvent.click(component)

fireEvent simulates events like clicks, input, change, etc. It allows you to test what changes when the event is triggered.

Creating a test

For testing, we use the functions describe and it / test . it / test is used for a single test case, whereas describe is used to group multiple test cases together.

describe and it / test requires two arguments, the first is a string which is the name of the test. It is best to put what you are testing in that field. The second is the function where you would carry out the test(s).

My tests are usually based on checking attributes or text content to see if they match expected values using the expect function.

expect(component.id).toEqual(props.id);

expect is used to compare a value with another in many different ways, and can determine the test outcome of the group based on its result.

Some examples are:

Equality ( toEqual ) :

expect(component.value).toEqual(10);

Comparison ( toBeGreaterThan , toBeLessThan )

expect(component.value).toBeGreaterThan(5);

Boolean ( toBeTruthy , toBeFalsy )

expect(component.activeElement).toBeTruthy();

Example test

Bring all these functions together, and you will have something like this:

import { render, fireEvent } from '@testing-library/svelte';
import Component from "../src/Component.svelte";
import SlotTest from "../../../test/slot/SlotTest.svelte";
describe("Component test", () => {
const props = {
id: "component",
class: "component-custom",
style: "width: 100%; height: 100%",
};
it("should render properly", () => {
const result = render(Component, { props });
expect(() => result).not.toThrow();
});
it("should render with slots", () => {
const result = render(SlotTest, { props: { component: Component, props } });
expect(() => result).not.toThrow();
});
// getElementsByClassName, getElementsByTagName, etc may be used
it("should have correct props", () => {
const { container } = render(Component, { props });
const component = container.getElementsByClassName("component")[0];
expect(component.getAttribute("style").toEqual(props.style);
});
it("fireEvent", async () => {
const { container } = render(Component, { props });
const component = container.getElementById("component");
expect(component.value).toEqual(1);
await fireEvent.click(component);
expect(component.value).toEqual(2);
});
});

After you have the test file ready, to start unit testing, use the command

jest

Jest can also only cover a certain file or folder you want by using an optional argument to set the directory name which you want to cover all the test files in.

jest src/components

Tip: Pre-Commits

Once you have your tests set up, I would recommend you automatically run them before every commit by setting up pre-commits. This would improve your workflow and removes the need for running a test every time you make modifications to your components. However, we won’t go through them in this article, but I would recommend libraries like pre-commit .

Conclusion

Unit Testing may seem overwhelming to you at first (it certainly felt that way for me), but it is easy to understand once you get the hang of it. Writing tests are also very simple thanks to the jest libraries. I hope this helps you on how to test your Svelte UI Components. Thank you for reading!

Relevant Links

Please read the documentation for both jest and Testing Library to get more information of what you can do with unit tests.

Also check out Svelte Society, which has recipes on components, design patterns and unit testing.

Level Up Coding

Thanks for being a part of our community! More content in the Level Up Coding publication.
Follow: Twitter, LinkedIn, Newsletter
Level Up is transforming tech recruiting ➡️ Join our talent collective

--

--

he/him. i like games, movies, music, and coding. i spend too much time online ryantanrk.github.io