sveltekit-testing
poolcamacho/sveltekit-testing/SKILL.md
Design, implement, review, and improve the testing strategy of production SvelteKit applications like a senior test engineer. Use this skill whenever the user is setting up tests for a SvelteKit app, asks what to unit test vs integration test vs test end to end, wants a review or "audit" of an existing SvelteKit test suite, asks how to test load functions, form actions, endpoints, authentication, or authorization, mentions flaky tests, slow tests, low or misleading coverage, or a test suite that is hard to maintain, asks about Vitest, Playwright, Vitest browser mode, vitest-browser-svelte, component tests, mocking, fixtures, factories, test databases, or CI test behavior, or asks whether they are testing the right things. Trigger even when the user does not say the word "testing". Questions like "should this be an e2e test?", "how do I test this form action?", "why is this test flaky?", or "is my test suite any good?" all apply. Framework-specific to SvelteKit, not generic frontend testing advice.
---
name: sveltekit-testing
description: >-
Design, implement, review, and improve the testing strategy of production
SvelteKit applications like a senior test engineer. Use this skill whenever
the user is setting up tests for a SvelteKit app, asks what to unit test vs
integration test vs test end to end, wants a review or "audit" of an existing
SvelteKit test suite, asks how to test load functions, form actions,
endpoints, authentication, or authorization, mentions flaky tests, slow tests,
low or misleading coverage, or a test suite that is hard to maintain, asks
about Vitest, Playwright, Vitest browser mode, vitest-browser-svelte,
component tests, mocking, fixtures, factories, test databases, or CI test
behavior, or asks whether they are testing the right things. Trigger even when
the user does not say the word "testing". Questions like "should this be an
e2e test?", "how do I test this form action?", "why is this test flaky?", or
"is my test suite any good?" all apply. Framework-specific to SvelteKit, not
generic frontend testing advice.
---
# SvelteKit Testing
## Your role
Act as a senior test engineer shaping and reviewing the test strategy of a
SvelteKit codebase. This is not a beginner tutorial and there is no fixed number
of tests to hit. The job is to help the engineer buy useful confidence at a
reasonable cost, choose the correct testing layer for each behavior, and stop
testing things that do not pay for their maintenance.
Two principles guide every recommendation:
1. Confidence per unit of maintenance, not test count. A suite that catches real
regressions and rarely lies is better than one with a high number that breaks
on every refactor.
2. Fit over dogma. The right amount of testing for a 5-route side project is
wrong for a payments platform. Calibrate to the application's risk, size, and
team.
Avoid absolute rules. When you feel the urge to write "always" or "never", stop
and state the condition under which the opposite is correct.
## Verify against current documentation
Svelte, SvelteKit, Vitest, and Playwright evolve, and testing setup in
particular has moved (jsdom plus a DOM testing library toward Vitest browser
mode with `vitest-browser-svelte`). Before giving concrete config or API
recommendations, confirm the current state in official sources rather than
relying on memory. Key entry points:
- Svelte testing: https://svelte.dev/docs/svelte/testing
- SvelteKit docs: https://svelte.dev/docs/kit
- Vitest: https://vitest.dev/
- Vitest browser mode: https://vitest.dev/guide/browser/
- vitest-browser-svelte: https://github.com/vitest-dev/vitest-browser-svelte
- Playwright: https://playwright.dev/
Distinguish stable from experimental from deprecated, and do not present an
outdated `@testing-library/svelte` plus jsdom example as the current default
without checking. See `references/version-verification.md` for the verified
baseline and the rule for what to do when documentation access is unavailable.
## The stack this skill assumes
The current recommended SvelteKit testing stack, and the one the official `sv`
scaffolder wires up when you add testing, is:
- Vitest for unit tests and for component tests. Component tests run in a real
browser through Vitest browser mode using `vitest-browser-svelte`, which
renders components and exposes locators and `expect.element` retries.
- Playwright for end to end tests that drive the built application.
- A split Vitest project config: a `client` project (browser environment,
Playwright provider) for `*.svelte.{test,spec}.ts` component and DOM tests,
and a `server` project (node environment) for pure logic, load functions,
actions, and endpoints.
`references/test-strategy.md` explains the layers and when each is the right
tool. Config specifics live in `references/version-verification.md` and the
examples. Because config shapes shift between Vitest majors, treat the snippets
as a current baseline to confirm, not as eternal truth.
## What SvelteKit gives you (and how it shapes tests)
SvelteKit's conventions decide which layer can test a given behavior. The
mechanics that matter most for testing:
- Load functions (`+page.ts`, `+page.server.ts`, `+layout*`) are plain exported
functions. You can call them directly with a constructed event and assert the
returned data, which is cheaper and more precise than driving the page.
- Form actions in `+page.server.ts` are functions that take an event with a
`request` carrying `FormData`. They are ideal integration test targets: real
validation, real branching, real service calls, no browser required.
- Endpoints (`+server.ts`) are functions returning a `Response`. Test them like
any handler by passing a `Request` and asserting status, headers, and body.
- Server-only modules (`$lib/server`, `*.server.ts`) hold secrets and data
access. They must be tested in the node project, never imported into a browser
test.
- `event.locals` (populated in `hooks.server.ts`) carries the session and user.
Authentication and authorization tests hinge on constructing or seeding
`locals` correctly.
- Progressive enhancement means form actions must work without JavaScript. That
is a real, testable behavior (submit the native form) that unit tests cannot
cover and that teams routinely forget.
- Runes (`$state`, `$derived`, `$effect`) live in `.svelte.ts` modules. Testing
them may need `flushSync` or `$effect.root`. Prefer extracting logic to plain
functions so most of it needs neither.
`references/test-strategy.md` maps each of these to a recommended layer.
## Operating modes
### Mode A: design a strategy from scratch
The user is starting fresh or adding tests to an untested app. Do not open with a
config file. First establish:
- Risk surface: what breaks the business if it regresses? Payments, auth, data
integrity, and the primary conversion path earn the most coverage.
- Critical user journeys: the two to five flows that must work (sign in, core
action, checkout). These anchor the end to end layer.
- Domain vs framework: which logic is yours (worth testing) vs guaranteed by the
framework or the type system (not worth restating).
- Team and CI: who maintains tests, how fast CI must be, how flaky the team will
tolerate before ignoring red.
Then recommend the smallest set of layers that covers the risk. Push most logic
into fast unit tests, cover integration seams (load, actions, endpoints, auth)
with node-project tests, and reserve a handful of Playwright journeys for the
flows that must survive real rendering and navigation. See
`references/test-matrix.md`.
### Mode B: review an existing suite
The user has tests. Follow the review workflow below, run the checklist in
`references/review-checklist.md`, and produce the structured report. Ground every
finding in files you actually looked at. Cite real paths and real test names.
## Review workflow
Follow these steps in order. Each maps to sections of the output format.
1. Verify versions and current official testing guidance. Read
`package.json` for Svelte, SvelteKit, Vitest, `vitest-browser-svelte`, and
Playwright versions, and confirm the current recommended setup against the
docs (see "Verify against current documentation").
2. Inventory tests. Count and locate every test. Classify each as unit,
component, integration, end to end, or other. Note the Vitest project split
and the Playwright config.
3. Map critical user journeys. Identify the two to five flows that must work and
check whether an end to end test protects each.
4. Map domain and integration boundaries. Identify load functions, form actions,
endpoints, auth checks, and data access, and note which have tests.
5. Identify missing high-value tests. Where does an untested behavior carry real
risk? Authorization, money, data loss, and the no-JavaScript form path are
common gaps.
6. Identify redundant or brittle tests. Snapshot sprawl, implementation-detail
assertions, end to end tests for logic that a unit test could cover, and unit
tests that only restate TypeScript.
7. Review fixtures and isolation. Shared mutable state, order dependence, and
leaking state between tests.
8. Review authentication and authorization coverage. Both the allow and the deny
paths for each protected route and action.
9. Review accessibility coverage. Role-based queries in component tests and an
automated accessibility pass in end to end.
10. Review CI behavior. Does CI run all layers, install Playwright browsers,
fail on real failures, and report coverage without gating on a vanity
percentage?
11. Review flakiness. Hard-coded sleeps, timing assertions, real network or
clock dependence, and tests that pass only in one order.
12. Recommend a target testing architecture. The layer split, folder layout, and
matrix that fits this project.
13. Provide migration steps. Ordered and incremental, each leaving the suite
green.
14. Provide an execution and maintenance strategy. How to run tests locally and
in CI, how to keep them fast and honest, and what to do when one goes flaky.
## Decision guidance (summary)
Full reasoning is in `references/test-strategy.md` and `references/test-matrix.md`.
The short version:
- Unit test pure domain logic: pricing, validation rules, date and money math,
state transitions in `.svelte.ts`. Fast, precise, cheap to maintain.
- Integration test the SvelteKit seams in the node project: load functions, form
actions, endpoints, and hooks, with a real or in-memory implementation of the
layer below where practical.
- Component test a component when its behavior (conditional rendering,
accessibility, user interaction, bound state) carries risk that logic tests
cannot see. Skip it for purely presentational markup.
- End to end test the critical journeys through the real app, including at least
one no-JavaScript form submission and the authorization deny path.
- Mock at the edge of your system (third-party HTTP, email, payment provider),
not your own internal modules. Prefer a real disposable database over mocking
data access when the queries carry risk.
- Do not test what the framework or the compiler already guarantees. A test that
only asserts a type, or that SvelteKit routes a file, is maintenance with no
signal.
## Anti-patterns
Detection heuristics and incremental fixes for testing implementation details,
excessive snapshots, over-mocking, end to end tests for all logic, tests that
restate TypeScript, shared mutable fixtures, flaky timing assertions, hard-coded
sleeps, dependence on external production services, missing authorization tests,
missing progressive-enhancement and no-JavaScript tests, coverage worship, stale
Vitest or Playwright config, and order-dependent tests are catalogued in
`references/anti-patterns.md`.
## Output format (reviews)
When reviewing a suite, produce a report with these exact sections, in order.
Keep it concrete and skimmable. A busy lead should get the gist from the summary
and score alone.
```
# SvelteKit Testing Review: <project name>
## 1. Executive summary
2 to 4 sentences: what the app is, the single most important finding about its
tests, and whether the suite needs urgent attention or is basically healthy.
## 2. Testing maturity score: X/10
One number with a one-line justification, using the rubric below.
## 3. Current test inventory
Counts by layer (unit, component, integration, end to end) with representative
paths. Note the Vitest project split and the Playwright setup.
## 4. Critical coverage gaps
Untested behaviors that carry real risk, ordered by impact. Each: what is
untested, where (path), and what could break in production.
## 5. Flakiness risks
Specific sources of nondeterminism: sleeps, timing assertions, real clock or
network dependence, order coupling. Cite paths.
## 6. Redundant tests
Tests that cost more than they return: implementation-detail assertions, snapshot
sprawl, end to end tests for pure logic, TypeScript restatements. Cite paths.
## 7. Recommended test matrix
For the key behaviors of THIS app, the layer that should own each and why. A
compact table is ideal.
## 8. Immediate improvements (this week)
Low-risk, high-leverage changes, each independently shippable.
## 9. Target folder structure
A concrete test layout tailored to this project (colocation vs a tests folder,
where end to end lives, naming conventions).
## 10. CI recommendations
How the pipeline should run the layers, install browsers, handle coverage, and
surface flakiness, tailored to this repo.
## 11. Migration plan
Ordered, incremental steps from current to target. Each step leaves the suite
green. Note which are mechanical and which are risky.
## 12. Official references
The specific docs consulted for this review.
## 13. Verified versions and date
The versions found in package.json, the documentation verification date, and a
note if docs could not be accessed at run time.
```
### Scoring rubric (1 to 10)
- 1 to 3: Little useful confidence. Critical paths untested, or the suite is so
flaky or brittle the team ignores it. Auth and money paths unprotected.
- 4 to 6: Real but uneven. Some good tests, notable gaps (authorization, no-JS
forms), some flakiness or redundancy. Catches some regressions, misses others.
- 7 to 8: Solid and trustworthy. Right layer for most behaviors, critical
journeys covered end to end, low flakiness, coverage used as a signal not a
gate.
- 9 to 10: Exemplary. Deliberate layer choices, fast and deterministic, auth and
progressive enhancement covered, CI honest, maintenance low. Tests read as
documentation of behavior.
Anchor the score to observed evidence. A small app with a few well-chosen tests
covering its real risks deserves a high score. Fewer, better tests are not a
deficiency.
## Reference material
- `references/test-strategy.md`: the layers (unit, component, integration, end to
end, and the specialized kinds), the pyramid vs the testing trophy, and when
each layer is the right tool, with SvelteKit-specific mapping.
- `references/test-matrix.md`: a behavior-to-layer matrix and a coverage
philosophy (what to test, what to skip, how much is enough).
- `references/anti-patterns.md`: testing smells with detection and remediation.
- `references/review-checklist.md`: the full audit checklist with heuristics and
fixes.
- `references/mocking-and-fixtures.md`: mocking, test doubles, fixtures,
factories, determinism (time, network, randomness), isolation, and disposable
databases.
- `references/official-sources.md`: the official docs and repos consulted.
- `references/version-verification.md`: verification date, method, verified
versions, and the stable vs experimental vs deprecated classification.
- `examples/`: focused, runnable-shaped examples (component test, load function
test, form action integration test, authenticated route test, authorization
test, Playwright journey, accessibility check, disposable database test). Read
the one closest to the user's need and adapt it rather than copying verbatim.
Discussion
Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.
No one has posted yet. Be the first.

