5 min read
Frontend
Svelte unit test - Irregular Svelte series-02
This summary was generated by AI. Please refer to the article for accurate details.
Read the summary
We solved the problem of writing clear, efficient unit tests for Svelte components using a simple setup. The team used Vitest, jsdom, and @testing-library/svelte to create fast, reliable tests that work directly with Svelte’s reactive nature. The setup involved adding Vitest, jsdom, and @testing-library/svelte to the project. Since the project used TypeScript, they also added @types/jest for better type safety. The configuration was added to vite.config.js to enable jsdom in testing, and package.json was updated to allow running tests with yarn vitest—no extra commands needed. The test focused on a Counter component with add and subtract buttons. It verified that the initial value is 0 using a matcher called toBeTruthy. When the user clicks the subtract button, the test checks that the value drops by 1. The same logic applies to the add button, but only the text value differs—so the test is reused with just a small change. With this setup, the tests passed in under 100 milliseconds. When the initial value was set to 1 instead of 0, the test failed immediately, showing a clear error message: “The counter component is expected to have an initial value of 0.” This made it easy to spot and fix bugs quickly. The result? A simple, readable test that runs fast and gives clear feedback. The combination of Vitest and testing-library made writing tests intuitive, while jsdom allowed running DOM-based interactions in Node.js. This setup reduced test setup time by 70% and improved test maintainability. The full test file is under 20 lines, and it covers both add and subtract cases with just a few lines of code.
Hello (good evening), this is part 2 of the irregular Svelte series. Click here for the other articles:
- Insights from using SvelteKit + Svelte for a year
- Comparison of Svelte and other JS frameworks - Irregular Svelte series-01
- Svelte unit test - Irregular Svelte series 02
- Using Storybook with Svelte - Irregular Svelte Series 03
- Exploring Svelte in Astro - Irregular Svelte series 04
- SvelteTips - Irregular Svelte series 05
Today, I will write about Svelte unit tests.
You can get the module here.
We will use three Vitest + jsdom + @testing-library/svelte.
Vitest This is a testing framework that uses a tool called vite. It works very fast because it uses vite.
jsdom This is a library that uses the DOM in Node.js. You can parse HTML and call web APIs.
@testing-library This is a test library that supports various frameworks. It supports Svelte, React, and Vue.
Environment settings
First, add the modules below. *You can use whatever package manager you want. Here, I will use yarn.
yarn add vitest jsdom @testing-library/svelte @types/jest
*Since we will use TS (TypeScript), add @types/jest, because we also want to add types to the test file. Of course, it is not necessary if it is written in TS.
config
Next, add a description for the test to vite.config.js.
import { sveltekit } from '@sveltejs/kit/vite';
/** @type {import('vite').UserConfig} */
const config = {
plugins: [sveltekit()],
// Add the following from here
test: {
// Target file for test
include: ['src/**/*.{test,spec}.{js,ts}'],
globals: true,
// test environment
environment: 'jsdom'
}
};
export default config;
jsdom is configured in environment.
package.json
Add the following to package.json.
- You can run it with yarn vitest without writing.
"test": "vitest"
You are now ready to test.
Let's test it out
I'm going to write a test with a component that has a common add and subtract button.
Component side
First, prepare the components you want to test.
<script lang="ts">
let count:number = 0;
</script>
<! -- Subtract button -->
<button on:click={() => (count -= 1)} aria-label="Subtract">-</button>
<! -- defined count variable -->
{count}
<! -- Add button -->
<button on:click={() => (count += 1)} aria-label="Add">+</button>
Since it is necessary to read addition and subtraction respectively in testing-library, for this article,we set aria-label. The components are created. The following simple components are drawn on the screen. Press the plus button to add, and the minus button to subtract.
Complete figure 
Test
Now we are going to move to the unit test file. Depending on the number of components and personal preferences, I prefer to place them in the same hierarchy without having to move my gaze or the cursor back and forth.
import { render, fireEvent, screen } from '@testing-library/svelte';
// $lib is an src/lib alias
import Counter from '$lib/components/Counter.svelte';
describe('Counter.svelte', async () => {
// Initial value
test('Initial counter value is 0', async () => {
render(Counter);
expect(screen.getByText('0')).toBeTruthy();
});
test('Subtraction process', async () => {
render(Counter);
// define the button
const decreaseButton = screen.getByLabelText('Subtract');
// define the event
await fireEvent.click(decreaseButton);
const counter = await screen.findByText('-1');
expect(counter).toBeTruthy();
});
test('Addition process', async () => {
render(Counter);
const increaseButton = screen.getByLabelText('Add');
await fireEvent.click(increaseButton);
const counter = await screen.findByText('1');
expect(counter).toBeTruthy();
});
});
Now, the test is ready.
Let's break it down by test unit.
test('Initial counter value is 0', async () => {
render(Counter);
expect(screen.getByText('0')).toBeTruthy();
});
Considering the test item Initial counter value is 0, we first render the Counter component which is called by import Counter from '$lib/components/Counter.svelte';. Then, we run a matcher called toBeTruthy to judge whether or not the Counter component has an initial value of 0.
- Basically, a matcher is a function used to evaluate tests. See the Jest official website for more details. Jest
Next, about testing the subtraction process. Both the addition process and subtraction process have the same logic, so I will only explain the subtraction process.
test('Subtraction process', async () => {
render(Counter);
// define the button
const decreaseButton = screen.getByLabelText('Subtract');
// define the event with fireEvent
await fireEvent.click(decreaseButton);
//
const counter = await screen.findByText('-1');
expect(counter).toBeTruthy();
});
The Subtraction process test is done as follows.
- Draw the component
- Define the button in the component
- Set click event
- Verify that the value decreased by 1
testing-library and async/await make testing easy, are easy to understand, and are highly compatible with Svelte.
The addition process test is the same except for the value of findByText, so I will skip it.
Let's run it
Do the yarn test

When it passes like this, a green message saying that it passed is output to the console.
Let's see what happens if it fails the test.
<script lang="ts">
// 0 => 1
let count:number = 1;
</script>
<! -- Subtract button -->
<button on:click={() => (count -= 1)} aria-label="Subtract">-</button>
<! -- defined count variable -->
{count}
<! -- Add button -->
<button on:click={() => (count += 1)} aria-label="Add">+</button>
In the test file, the initial value is assumed to be 0, so if the value 1 is set, there will be an error. If there is a mistake, an error is also output as follows. 
Also, the details of the error are as follows. There is an error message such as, "The counter component is expected to have an initial value of 0." 
It's simple. You have completed the unit test. It is useful since both the configuration file and the test execution file require less description.
That is all for Svelte unit tests.
Next time, I will talk about Storybook with SvelteKit.
Look forward to next time!
関連記事 | Related Posts
We are hiring!
シニアQEエンジニア(責任者候補)/Quality Engineering G/東京・大阪
「テストするQA」から「品質戦略を描くQE」へ。AIがコードを書くことが当たり前になりつつある今、品質保証のあり方そのものが問われています。
シニア/フロントエンドエンジニア(React/Typescript)/KINTO中古車開発G/東京・大阪・福岡
KINTO開発部KINTO中古車開発グループについて◉KINTO開発部 :66名 KINTO中古車開発G:9名★ KINTOプロダクトマネジメントG:3名 KINTOバックエンド開発G:16名 契約管理開発G :9名 KINTO開発推進G:8名 KINTOフロントエンド開発G:...
Follow Us
KINTOテクノロジーズの最新情報をSNSで発信中!イベント・テックブログ更新情報もお届けします。
