Snippets are difficult to test directly. It's usually easier to structure your code so that you can test the user-facing results, leaving any snippets as an implementation detail. However, if snippets are an important developer-facing API of your component, there are several strategies you can use.
For simple snippets, you can use a wrapper component and "dummy" children to
test them. Setting data-testid attributes can be helpful when testing slots in
this manner.
<script>
let { children } = $props()
</script>
<h1>
{@render children?.()}
</h1><script>
import Subject from './basic-snippet.svelte'
</script>
<Subject>
<span data-testid="child"></span>
</Subject>import { render, screen, within } from '@testing-library/svelte'
import { expect, test } from 'vitest'
import SubjectTest from './basic-snippet.test.svelte'
test('basic snippet', () => {
render(SubjectTest)
const heading = screen.getByRole('heading')
const child = within(heading).getByTestId('child')
expect(child).toBeInTheDocument()
})For more complex snippets, e.g. where you want to check arguments, you can use Svelte's createRawSnippet API.
<script>
let { name, message } = $props()
const greeting = $derived(`Hello, ${name}!`)
</script>
<p>
{@render message?.(greeting)}
</p>import { render, screen } from '@testing-library/svelte'
import { createRawSnippet } from 'svelte'
import { expect, test } from 'vitest'
import Subject from './complex-snippet.svelte'
test('renders greeting in message snippet', () => {
render(Subject, {
name: 'Alice',
message: createRawSnippet((greeting) => ({
render: () => `<span data-testid="message">${greeting()}</span>`,
})),
})
const message = screen.getByTestId('message')
expect(message).toHaveTextContent('Hello, Alice!')
})