本文へスキップ / Skip to main content
KINTO Tech Blog

5 min read

Frontend

Svelte unit test - Irregular Svelte series-02

Svelte unit test - Irregular Svelte series-02 cover
Speed

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:

  1. Insights from using SvelteKit + Svelte for a year
  2. Comparison of Svelte and other JS frameworks - Irregular Svelte series-01
  3. Svelte unit test - Irregular Svelte series 02
  4. Using Storybook with Svelte - Irregular Svelte Series 03
  5. Exploring Svelte in Astro - Irregular Svelte series 04
  6. 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.

https://vitest.dev/

jsdom This is a library that uses the DOM in Node.js. You can parse HTML and call web APIs.

https://github.com/jsdom/jsdom

@testing-library This is a test library that supports various frameworks. It supports Svelte, React, and Vue.

https://testing-library.com/docs/svelte-testing-library/intro/

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.

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.

src/lib/components/Counter.svelte
<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 failed

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.

src/lib/Counter.test.ts
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
  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
  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

Test pass

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.

src/lib/components/Counter.svelte
<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. Test failed

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." Test failed

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!

Facebook

Follow Us

XConnpassWantedly

KINTOテクノロジーズの最新情報をSNSで発信中!イベント・テックブログ更新情報もお届けします。