Skip to content

Astro Testing — Component and Page Testing

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Astro Testing. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Astro testing: write unit tests for components, integration tests for pages, use Vitest, and test SSR endpoints for reliable deployments.

In this lesson, you'll set up Vitest for Astro, write unit tests for components, test page rendering, and validate API endpoints.

What You'll Learn

How to install Vitest, configure testing for Astro, write component and page tests, test API endpoints, and run tests in CI.

Why It Matters

Testing catches regressions before deployment. Automated tests ensure your site works correctly after changes, especially with dynamic content and SSR.

Real-World Use

DodaTech runs a test suite with Vitest that validates every tutorial page renders correctly and all API endpoints return expected responses.

flowchart LR
    A[Write Tests] --> B[Vitest Runner]
    B --> C[Component Tests]
    B --> D[Page Tests]
    B --> E[API Tests]
    C --> F[Pass/Fail]
    style B fill:#ff5a03,color:#fff

Setup Vitest

Install Vitest and Astro's test utilities:

npm install -D vitest @astrojs/test-utils

Configure in vitest.config.ts:

import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    environment: "node",
    globals: true,
  },
});

Testing a Component

Create src/components/__tests__/Card.test.ts:

import { test, expect } from "vitest";
import { render } from "@astrojs/test-utils";

test("Card renders title and description", async () => {
  const html = await render("./src/components/Card.astro", {
    props: { title: "Test", description: "A test card" },
  });
  expect(html).toContain("Test");
  expect(html).toContain("A test card");
});

Testing a Page

Test that a page renders correctly:

import { test, expect } from "vitest";
import { renderPage } from "@astrojs/test-utils";

test("Homepage renders with correct title", async () => {
  const html = await renderPage("./src/pages/index.astro");
  expect(html).toContain("<h1>Welcome</h1>");
});

test("About page has meta description", async () => {
  const html = await renderPage("./src/pages/about.astro");
  expect(html).toContain('meta name="description"');
});

Testing API Endpoints

Test SSR API endpoints:

import { test, expect } from "vitest";
import { renderEndpoint } from "@astrojs/test-utils";

test("GET /api/users returns JSON", async () => {
  const response = await renderEndpoint("./src/pages/api/users.ts", {
    method: "GET",
  });
  expect(response.status).toBe(200);
  expect(response.headers.get("content-type")).toContain("application/json");
  const data = await response.json();
  expect(Array.isArray(data)).toBe(true);
});

test("POST /api/contact validates input", async () => {
  const response = await renderEndpoint("./src/pages/api/contact.ts", {
    method: "POST",
    body: JSON.stringify({}),
  });
  expect(response.status).toBe(400);
});

Testing with Content Collections

Mock content collection data:

import { test, expect } from "vitest";
import { renderPage } from "@astrojs/test-utils";

test("Blog index lists posts", async () => {
  const html = await renderPage("./src/pages/blog/index.astro", {
    collections: {
      blog: [
        { slug: "post-1", data: { title: "Post 1", date: new Date() } },
        { slug: "post-2", data: { title: "Post 2", date: new Date() } },
      ],
    },
  });
  expect(html).toContain("Post 1");
  expect(html).toContain("Post 2");
});

Running Tests

npx vitest run        # Run tests once
npx vitest            # Watch mode
npx vitest --coverage # With coverage report

Common Mistakes

  1. Not using @astrojs/test-utils: Direct rendering of .astro files without the test utils fails. Always use the test utilities.
  2. Testing framework components without browser environment: React/Vue/Svelte components may need jsdom environment. Configure in vitest.config.ts.
  3. Forgetting async/await: render() and renderPage() return promises. Always await them.
  4. Testing implementation details: Test what the user sees (HTML output), not internal component state.
  5. Not testing error states: Test 404 pages, error boundaries, and failed API responses, not just the happy path.

Practice Questions

  1. What test runner does Astro recommend? Answer: Vitest. It's fast, compatible with Vite, and has Astro-specific test utilities.

  2. How do you test an Astro component's output? Answer: Use render() from @astrojs/test-utils and check the returned HTML string.

  3. How do you test API endpoints? Answer: Use renderEndpoint() with the endpoint file path and request options (method, body, headers).

  4. Why test content collection pages? Answer: To verify pages render correctly with different data, catch missing fields, and validate template logic.

Challenge

Write a test suite for a blog site: test that the blog index lists posts, that individual post pages render with correct titles, that the 404 page appears for unknown slugs, and that the RSS feed generates valid XML.

Mini Project

Add testing to an existing Astro project: install Vitest, write component tests for three components, page tests for two pages, and API tests for one endpoint. Set up a CI script that runs tests on every Git push.

FAQ

Can I test with Jest instead of Vitest?

: Yes, but Vitest is recommended for better Vite compatibility and faster execution.

How do I test client-side interactivity?

: Use Vitest with jsdom environment and test island components by importing them directly.

Can I run tests during the build?

: Yes. Add vitest run to your build script or CI pipeline to fail the build on test failures.

How do I mock external API calls in tests?

: Use Vitest's vi.mock() to mock fetch requests or database calls in endpoint tests.

What's Next

Apply everything you've learned in the Astro Final Project where you'll build a complete production-ready Astro site.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro