Unit Tests With Vitest, E2E With Playwright
Testing
Test plain functions with Vitest. Test pages end-to-end with Playwright against the built site.
What you'll learn
- Set up Vitest in an Astro project
- Write a unit test for a helper
- Run an E2E test against a built site
Two layers of testing cover most Astro sites:
- Vitest for plain JS/TS — helpers, schemas, business logic
- Playwright for the rendered site — pages render, links work, islands hydrate
Vitest
npm install -D vitest // vitest.config.mjs
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
include: ["src/**/*.{test,spec}.ts"],
},
}); // src/lib/dates.test.ts
import { describe, it, expect } from "vitest";
import { formatDate } from "./dates";
describe("formatDate", () => {
it("formats a Date", () => {
expect(formatDate(new Date("2026-05-12"))).toBe("May 12, 2026");
});
}); Run with npx vitest.
Testing Astro Components
Astro provides experimental component-test helpers in
astro:test. They’re useful for testing component output as HTML.
For most sites, a Playwright check against the rendered page
covers it better.
Playwright — End-to-End
npm init playwright@latest The wizard creates a playwright.config.ts and a tests/ folder.
// tests/home.spec.ts
import { test, expect } from "@playwright/test";
test("home page", async ({ page }) => {
await page.goto("/");
await expect(page.getByRole("heading", { name: /welcome/i })).toBeVisible();
});
test("counter hydrates", async ({ page }) => {
await page.goto("/counter");
const btn = page.getByRole("button", { name: /count/i });
await btn.click();
await btn.click();
await expect(btn).toHaveText(/Count: 2/);
}); Configure Playwright to run against npm run dev (or
npm run preview for built output):
// playwright.config.ts
export default defineConfig({
webServer: {
command: "npm run dev",
url: "http://localhost:4321",
reuseExistingServer: !process.env.CI,
},
use: { baseURL: "http://localhost:4321" },
}); What To Test
- Critical pages render the expected content
- Forms submit and show success / error
- Islands hydrate and respond to interaction
- Navigation works (links, view transitions)
Don’t test framework internals (Astro’s own behavior). Test YOUR business logic and YOUR site’s flows.
Up Next
Performance audits.
Performance →