Testing Next.js Applications
Set up unit tests with Vitest/Jest and end-to-end tests with Playwright for a Next.js project.
Levels of Testing
Unit Tests
Test a single function or component in isolation — fast, focused, and cheap to run.
Integration Tests
Test how several pieces work together, like a form calling a Server Action.
End-to-End (E2E) Tests
Drive a real browser through your app exactly as a user would.
Unit Testing Components
Vitest (or Jest) combined with React Testing Library is the standard setup for testing individual components.
npm install --save-dev vitest @testing-library/react @testing-library/jest-dom jsdom// Card.test.tsximport { render, screen } from '@testing-library/react';import Card from './Card';
test('renders the card title', () => { render(<Card title="Hello">Content</Card>); expect(screen.getByText('Hello')).toBeInTheDocument();});Because Server Components are async and render on the server, tooling for unit-testing them directly is still evolving — most teams test the plain functions they call, and lean on end-to-end tests for full-page behavior.
Testing Server Actions
Since a Server Action is just an async function, you can often test its logic directly by importing and calling it with mocked inputs, separate from any UI.
import { createPost } from './actions';
test('rejects a title that is too short', async () => { const formData = new FormData(); formData.set('title', 'Hi');
const result = await createPost(null, formData); expect(result.error).toBe('Title must be at least 3 characters.');});End-to-End Testing with Playwright
Playwright drives a real browser against your running app, verifying full user flows — navigation, form submission, authentication — the way a real visitor would experience them.
npm init playwright@latestimport { test, expect } from '@playwright/test';
test('user can create a post', async ({ page }) => { await page.goto('/blog/new'); await page.fill('input[name="title"]', 'My First Post'); await page.click('button[type="submit"]'); await expect(page.getByText('My First Post')).toBeVisible();});FAQs
For most real projects, yes — unit tests catch logic bugs quickly and cheaply, while end-to-end tests catch integration issues that only show up in a real browser.
Indirectly, yes — by triggering the form or button that calls the Server Action and asserting on the resulting UI, exactly as a real user's interaction would.
Summary
Unit tests, Server Action tests, and Playwright end-to-end tests together give solid coverage across a Next.js app's logic and user flows. Next, you'll look specifically at performance optimization techniques.