Component testing helps you check if your Svelte parts work right. Testing Library makes this easy by focusing on what users see and do.
Component testing with Testing Library in Svelte
import { render, fireEvent } from '@testing-library/svelte'; import ComponentName from './ComponentName.svelte'; test('description', async () => { const { getByText } = render(ComponentName); const button = getByText('Click me'); await fireEvent.click(button); expect(getByText('Changed text')).toBeInTheDocument(); });
render() creates a test version of your component.
fireEvent simulates user actions like clicks or typing.
import { render } from '@testing-library/svelte'; import Hello from './Hello.svelte'; test('shows greeting', () => { const { getByText } = render(Hello); getByText('Hello, world!'); });
import { render, fireEvent } from '@testing-library/svelte'; import Counter from './Counter.svelte'; test('increments count on click', async () => { const { getByText } = render(Counter); const button = getByText('Count: 0'); await fireEvent.click(button); getByText('Count: 1'); });
This example shows a simple counter button. The test renders the button, checks the initial count, clicks it, and then checks the updated count. It uses an accessible label for the button to help find it in the test.
/* Counter.svelte */ <script> let count = 0; function increment() { count += 1; } </script> <button on:click={increment} aria-label="Increment count">Count: {count}</button> /* Counter.test.js */ import { render, fireEvent } from '@testing-library/svelte'; import Counter from './Counter.svelte'; test('button increments count when clicked', async () => { const { getByRole } = render(Counter); const button = getByRole('button', { name: 'Increment count' }); expect(button).toHaveTextContent('Count: 0'); await fireEvent.click(button); expect(button).toHaveTextContent('Count: 1'); });
Use accessible roles and labels to find elements in tests for better clarity and reliability.
Testing Library encourages testing what users see, not internal details.
Always await user events like clicks to handle async updates correctly.
Component testing checks if your Svelte parts behave as users expect.
Testing Library helps simulate user actions and find elements by what they show.
Write tests that focus on visible output and user interaction, not internal code.
Practice
Solution
Step 1: Understand component testing purpose
Component testing focuses on how the component behaves and appears to users, not internal code details.Step 2: Match Testing Library's approach
Testing Library encourages testing visible output and user interactions, aligning with user perspective testing.Final Answer:
To check if the component behaves correctly from a user's perspective -> Option AQuick Check:
User-focused testing = To check if the component behaves correctly from a user's perspective [OK]
- Testing internal variables instead of user output
- Confusing performance testing with component testing
- Checking file size instead of behavior
Solution
Step 1: Identify the official Testing Library package for Svelte
The official package is '@testing-library/svelte' which exports the render function.Step 2: Check correct import syntax
The render function is a named export, so it must be imported with curly braces.Final Answer:
import { render } from '@testing-library/svelte'; -> Option CQuick Check:
Named import from '@testing-library/svelte' = import { render } from '@testing-library/svelte'; [OK]
- Using default import instead of named import
- Importing from wrong package name
- Using incorrect function name like renderComponent
import { render } from '@testing-library/svelte';
import Button from './Button.svelte';
test('button shows correct label', () => {
const { getByText } = render(Button, { props: { label: 'Click me' } });
const button = getByText('Click me');
expect(button).toBeInTheDocument();
});Solution
Step 1: Analyze render usage with props
The Button component is rendered with prop label set to 'Click me', which should display that text.Step 2: Check getByText and assertion
getByText('Click me') finds the button element with that text, so expect(button).toBeInTheDocument() passes.Final Answer:
The test passes because the button with label 'Click me' is rendered -> Option BQuick Check:
Rendered label found by getByText = The test passes because the button with label 'Click me' is rendered [OK]
- Assuming getByText fails when text is passed as prop
- Confusing render syntax with props
- Thinking toBeInTheDocument fails without explicit import
import { render } from '@testing-library/svelte';
import Counter from './Counter.svelte';
test('increments count on button click', () => {
const { getByText } = render(Counter);
const button = getByText('Increment');
button.click();
expect(getByText('Count: 1')).toBeInTheDocument();
});Solution
Step 1: Check how user events are simulated
Testing Library requires using fireEvent or userEvent to simulate clicks, not direct button.click() calls.Step 2: Verify other parts of the test
Counter is imported, getByText queries are correct, and initial props are optional here.Final Answer:
Using button.click() instead of fireEvent.click(button) -> Option DQuick Check:
Use fireEvent for clicks, not button.click() [OK]
- Calling element.click() directly instead of fireEvent
- Forgetting to import the component
- Using wrong text in getByText query
import { render, fireEvent, waitFor } from '@testing-library/svelte';
import MessageToggle from './MessageToggle.svelte';
test('shows message after click', async () => {
const { getByText, queryByText } = render(MessageToggle);
expect(queryByText('Hello!')).toBeNull();
const button = getByText('Show Message');
await fireEvent.click(button);
await waitFor(() => getByText('Hello!'));
expect(getByText('Hello!')).toBeInTheDocument();
});Solution
Step 1: Understand conditional rendering after event
The message appears only after clicking the button, so the test must wait for it asynchronously.Step 2: Check usage of waitFor and fireEvent
fireEvent.click simulates the click, and waitFor waits until getByText('Hello!') finds the message, ensuring correct timing.Final Answer:
This test correctly waits for the message to appear after the click -> Option AQuick Check:
Use waitFor to await async UI changes = This test correctly waits for the message to appear after the click [OK]
- Not waiting for async UI updates before asserting
- Using setTimeout instead of waitFor
- Confusing queryByText and getByText usage
Ready to prove it?
Pass the test and this pattern moves unknown
