Home Quizzes Leaderboard Competitions Learn Hire Us
About Contact
Log In Sign Up
Learn Next.js Testing --- Jest & Playwright

Testing --- Jest & Playwright

⏱ 18 min read read
Setup Jest + Testing Library:

npm install -D jest jest-environment-jsdom @testing-library/react

@testing-library/jest-dom @types/jest

npx jest --init

// jest.config.ts

import type { Config } from 'jest';

const config: Config = {

testEnvironment: 'jsdom',

setupFilesAfterFramework: ['<rootDir>/jest.setup.ts'],

moduleNameMapper: { '^@/(.*)$': '<rootDir>/$1' },

};

export default config;

// jest.setup.ts

import '@testing-library/jest-dom';

Unit Testing Components:

import { render, screen, fireEvent } from '@testing-library/react';

import Counter from '@/components/Counter';

describe('Counter', () => {

it('renders initial count of 0', () => {

render(<Counter />);

expect(screen.getByText('Count: 0')).toBeInTheDocument();

});

it('increments on button click', () => {

render(<Counter />);

fireEvent.click(screen.getByRole('button', { name: /\+1/i }));

expect(screen.getByText('Count: 1')).toBeInTheDocument();

});

});

Playwright --- End-to-End Testing:

npm init playwright@latest

// tests/home.spec.ts

import { test, expect } from '@playwright/test';

test('homepage loads and shows title', async ({ page }) => {

await page.goto('http://localhost:3000');

await expect(page).toHaveTitle(/My App/);

await expect(page.getByRole('heading', { name: 'Hello'
})).toBeVisible();

});

test('can add a student', async ({ page }) => {

await page.goto('/students');

await page.getByPlaceholder('Name').fill('Alice');

await page.getByPlaceholder('Grade').fill('92');

await page.getByRole('button', { name: 'Add' }).click();

await expect(page.getByText('Alice: 92')).toBeVisible();

});

Jest + Testing Library = unit tests for pure functions and React
components.

Playwright = browser-based E2E tests (Chrome, Firefox, Safari).

Testing Library philosophy: test behaviour, not implementation.

Query priority: getByRole > getByLabelText > getByText >
getByTestId.

Run: npm test (Jest) | npx playwright test (E2E)
Code Example
// \_\_tests\_\_/StudentList.test.tsx

import { render, screen, fireEvent, waitFor } from
'@testing-library/react';

import '@testing-library/jest-dom';

import StudentManager from '@/components/StudentManager';

const mockStudents = [

{ id: 1, name: 'Alice', grade: 92 },

{ id: 2, name: 'Bob', grade: 58 },

];

describe('StudentManager', () => {

it('displays all students', () => {

render(<StudentManager initialStudents={mockStudents} />);

expect(screen.getByText('Alice')).toBeInTheDocument();

expect(screen.getByText('Bob')).toBeInTheDocument();

});

it('shows Pass/Fail badge correctly', () => {

render(<StudentManager initialStudents={mockStudents} />);

const badges = screen.getAllByRole('status');

expect(badges[0]).toHaveTextContent('Pass');

expect(badges[1]).toHaveTextContent('Fail');

});

it('adds a new student', async () => {

render(<StudentManager initialStudents={[]} />);

fireEvent.change(screen.getByPlaceholderText('Name'), { target: {
value: 'Carol' } });

fireEvent.change(screen.getByPlaceholderText('Grade'), { target: {
value: '85' } });

fireEvent.click(screen.getByRole('button', { name: /add/i }));

await waitFor(() =>
expect(screen.getByText('Carol')).toBeInTheDocument());

});

it('removes a student on delete click', async () => {

render(<StudentManager initialStudents={mockStudents} />);

const deleteButtons = screen.getAllByRole('button', { name:
/remove|✕/i });

fireEvent.click(deleteButtons[0]);

await waitFor(() =>
expect(screen.queryByText('Alice')).not.toBeInTheDocument());

});

it('shows error for invalid grade', () => {

render(<StudentManager initialStudents={[]} />);

fireEvent.change(screen.getByPlaceholderText('Name'), { target: {
value: 'Dave' } });

fireEvent.change(screen.getByPlaceholderText('Grade'), { target: {
value: '150' } });

fireEvent.click(screen.getByRole('button', { name: /add/i }));

expect(screen.getByRole('alert')).toBeInTheDocument();

});

});
← Performance --- Caching, Suspense & Stre Internationalisation (i18n) →

Log in to track your progress and earn badges as you complete lessons.

Log In to Track Progress