Menu

19. Testing

Next.js Master Roadmap - IT Technology

This chapter explores testing methodologies for Next.js applications, covering unit tests with Jest and Vitest, component tests using React Testing Library, and end-to-end tests with Playwright and Cypress. Learn setup, best practices, and real‑world examples to ensure robust, maintainable code.

No MCQ questions available for this chapter.

19. Testing

Introduction

Testing is a cornerstone of reliable software development. In the Next.js ecosystem, a well‑tested application gives developers confidence when refactoring, adding features, or deploying to production. This chapter walks you through the three main testing layers commonly used in Next.js projects: unit testing, component testing, and end‑to‑end (E2E) testing. For each layer we introduce the most popular tools—Jest, Vitest, React Testing Library, Playwright, and Cypress—show how to configure them, write effective tests, and integrate them into a continuous integration (CI) pipeline.

Why Testing Matters in Next.js

  • Early bug detection: Unit tests catch logic errors before they propagate.
  • Component confidence: React Testing Library ensures UI behaves as expected from the user’s perspective.
  • User‑flow validation: Playwright and Cypress simulate real browsers, catching integration and routing issues.
  • Documentation: Tests serve as living documentation of intended behavior.
  • Refactoring safety: A solid test suite lets you upgrade Next.js, React, or dependencies with minimal risk.

Setting Up the Testing Environment

Project Initialization

Start with a fresh Next.js app (or use an existing one).

npx create-next-app@latest my-next-app --typescript

Change into the project folder and install the testing dependencies.

Jest Configuration

Jest is the traditional test runner for JavaScript/TypeScript projects. Install the core packages:

npm i -D jest @types/jest ts-jest

Create a jest.config.js file at the project root:

module.exports = { preset: 'ts-jest', testEnvironment: 'jsdom', moduleNameMapper: { // Handle CSS imports (with CSS modules) '\\.(css|less|scss|sass)$': 'identity-obj-proxy', // Handle image imports '\\.(gif|ttf|eot|svg|png)$': '/__mocks__/fileMock.js', }, setupFilesAfterEnv: ['/jest.setup.js'], };

Install identity-obj-proxy for CSS mocking and create a simple file mock:

npm i -D identity-obj-proxy
// __mocks__/fileMock.js module.exports = 'test-file-stub';

Add a basic Jest setup file to extend matchers:

// jest.setup.js import '@testing-library/jest-dom';

Vitest Configuration (Alternative)

Vitest is a Vite‑native test runner that offers blazing‑fast hot module replacement (HMR) during test development. Install Vitest and related plugins:

npm i -D vitest @vitest/ui happy-dom

Create vitest.config.ts:

import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { globals: true, environment: 'happy-dom', setupFiles: './vitest.setup.ts', // Alias for Next.js absolute imports alias: { '@/*': ['./*'], }, }, });

Create a setup file to import DOM matchers:

// vitest.setup.ts import '@testing-library/jest-dom';

Unit Testing with Jest and Vitest

Unit tests focus on pure functions, utility modules, and small pieces of business logic. They are fast, deterministic, and easy to maintain.

Testing Utility Functions

Consider a utility that formats a price:

// lib/formatPrice.ts export function formatPrice(amount: number, currency = 'USD'): string { return new Intl.NumberFormat('en-US', { style: 'currency', currency, }).format(amount); }

Write a Jest test:

// __tests__/formatPrice.test.ts import { formatPrice } from '../lib/formatPrice'; describe('formatPrice', () => { test('formats a whole number as USD', () => { expect(formatPrice(1000)).toBe('$1,000.00'); }); test('accepts a custom currency', () => { expect(formatPrice(2500, 'EUR')).toBe('€2,500.00'); }); test('handles decimal values', () => { expect(formatPrice(1234.5)).toBe('$1,234.50'); }); });

The same test works with Vitest; just run