포스트

[이제와서 시작하는 Next.js 마스터하기 #12] 테스팅으로 안정성 확보하기

[이제와서 시작하는 Next.js 마스터하기 #12] 테스팅으로 안정성 확보하기

“테스트 없는 코드는 레거시!” - Jest와 Playwright로 안정성을 확보하세요!

🎯 이 글에서 배울 내용

  • Jest로 단위 테스트
  • React Testing Library로 컴포넌트 테스트
  • Playwright E2E 테스트
  • 테스트 Best Practices

예상 소요 시간: 30분 난이도: 중급


🧪 Jest 설정

1
npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// jest.config.js
const nextJest = require('next/jest');

const createJestConfig = nextJest({
  dir: './',
});

const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testEnvironment: 'jest-environment-jsdom',
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/$1',
  },
};

module.exports = createJestConfig(customJestConfig);
1
2
// jest.setup.js
import '@testing-library/jest-dom';

✅ 컴포넌트 테스트

1
2
3
4
5
6
7
8
// components/Button.tsx
export function Button({ onClick, children, disabled }) {
  return (
    <button onClick={onClick} disabled={disabled}>
      {children}
    </button>
  );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// components/Button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from './Button';

describe('Button', () => {
  it('renders correctly', () => {
    render(<Button>Click me</Button>);
    expect(screen.getByText('Click me')).toBeInTheDocument();
  });

  it('calls onClick when clicked', () => {
    const handleClick = jest.fn();
    render(<Button onClick={handleClick}>Click me</Button>);

    fireEvent.click(screen.getByText('Click me'));
    expect(handleClick).toHaveBeenCalledTimes(1);
  });

  it('is disabled when disabled prop is true', () => {
    render(<Button disabled>Click me</Button>);
    expect(screen.getByText('Click me')).toBeDisabled();
  });
});

🎭 Playwright E2E 테스트

1
2
npm install -D @playwright/test
npx playwright install
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: './e2e',
  use: {
    baseURL: 'http://localhost:3000',
  },
  webServer: {
    command: 'npm run dev',
    port: 3000,
    reuseExistingServer: !process.env.CI,
  },
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// e2e/auth.spec.ts
import { test, expect } from '@playwright/test';

test.describe('Authentication', () => {
  test('should login successfully', async ({ page }) => {
    await page.goto('/login');

    await page.fill('input[name="email"]', 'test@example.com');
    await page.fill('input[name="password"]', 'password123');
    await page.click('button[type="submit"]');

    await expect(page).toHaveURL('/dashboard');
    await expect(page.locator('text=Welcome')).toBeVisible();
  });

  test('should show error with invalid credentials', async ({ page }) => {
    await page.goto('/login');

    await page.fill('input[name="email"]', 'wrong@example.com');
    await page.fill('input[name="password"]', 'wrongpassword');
    await page.click('button[type="submit"]');

    await expect(page.locator('text=Invalid credentials')).toBeVisible();
  });
});

🎯 오늘 배운 내용 정리

  1. 단위 테스트
    • Jest 설정
    • React Testing Library
  2. E2E 테스트
    • Playwright
    • 사용자 시나리오 테스트

📚 시리즈 네비게이션


“테스트는 자신감입니다!” ✅

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.