This episode covers code quality through testing: unit testing with Vitest and Svelte Testing Library, integration testing for API routes, E2E testing with Playwright, plus static analysis and type checking.

The larger an application grows, the more expensive an error discovered only in production becomes. Episode 16 covers testing and quality in SvelteKit: unit testing with Vitest and Svelte Testing Library, integration testing for API routes, E2E testing with Playwright, plus static analysis and type checking.
Testing is not just about running code — it builds the confidence to change code without fear of breaking what already works. A good test layer works like a safety net: unit tests for the smallest logic, integration tests between modules, and E2E tests for real user flows.
After this episode, you have a complete testing setup that runs in CI and gives fast feedback on every change.
Vitest runs on top of Vite, so it reuses the same project configuration as SvelteKit. To test components, add the jsdom environment and the testing library plugin.
import { defineConfig } from "vitest/config";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import { svelteTesting } from "@testing-library/svelte/vite";
export default defineConfig({
plugins: [svelte(), svelteTesting()],
test: {
environment: "jsdom",
include: ["src/**/*.test.ts"]
}
});Svelte Testing Library lets you render components and interact with them like a user would. Assertions focus on observable results, not internal implementation details.
import { render, screen } from "@testing-library/svelte";
import { describe, it, expect } from "vitest";
import Tombol from "./Tombol.svelte";
describe("Tombol", () => {
it("menampilkan label dan merespons klik", async () => {
render(Tombol, { props: { label: "Kirim" } });
const tombol = screen.getByText("Kirim");
expect(tombol).toBeTruthy();
});
});Server logic such as server actions and load functions can be tested directly without a browser: call the handler with a mock event object and inspect the result. This is far faster than E2E for validating business rules.
import { describe, it, expect } from "vitest";
import { actions } from "./+page.server.js";
describe("action simpan", () => {
it("menolak nama yang terlalu pendek", async () => {
const form = new FormData();
form.set("nama", "ab");
const hasil = await actions.simpan({
request: new Request("http://localhost", { method: "POST", body: form })
});
expect(hasil.status).toBe(400);
});
});For a +server.js endpoint, create real Request and URL objects and call the handler method. This way the paths for query parsing, headers, and response building are tested end-to-end at the code level, without needing to run a server.
Playwright tests the application as it actually runs in a browser. The default configuration already covers Chromium, Firefox, and WebKit, so cross-browser compatibility is tested.
npm install -D @playwright/test
npx playwright install --with-deps
npx playwright testE2E mimics user behavior: visiting pages, filling forms, and checking results. Because it runs in a real browser, it catches issues that unit tests miss, such as hydration and cross-component interactions.
import { test, expect } from "@playwright/test";
test("login berhasil membawa ke dashboard", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill("user@example.com");
await page.getByLabel("Password").fill("rahasia");
await page.getByRole("button", { name: "Masuk" }).click();
await expect(page).toHaveURL("/dashboard");
});Certain kinds of errors — wrong props, incorrect route options, mismatched data types — do not surface at runtime but can be detected by a type checker. svelte-check analyzes the entire project, including .svelte files.
npx svelte-kit sync
npx svelte-check --tsconfig ./tsconfig.jsonCombine all quality tools into a single command in package.json, for example npm run check which runs svelte-kit sync then svelte-check, and npm run lint for ESLint. Run both in CI before the build so code that does not meet standards never reaches production.
Key takeaways:
svelte-check catches type errors across the whole project.In the next episode we get into accessibility & UX: ARIA roles, keyboard navigation and focus management, semantic HTML and accessible forms, responsive layout and inclusive design, plus the fundamentals of internationalization and localization.