React Testing Library로 테스트 작성하기 – 초보자도 쉽게 따라하는 완벽 가이드

React Testing Library로 테스트 작성하기 – 초보자도 쉽게 따라하는 완벽 가이드

도입 – 학습 목표 및 필요성

React Testing Library로 테스트 작성하기는 현대적인 React 애플리케이션 개발에서 필수적인 기술입니다. 이 튜토리얼을 통해 사용자 중심의 테스트 작성 방법을 배우고, 실제 사용자가 앱을 사용하는 방식으로 컴포넌트를 검증하는 방법을 익힐 수 있습니다. React Testing Library는 구현 세부사항이 아닌 사용자 행동에 집중하여 더 유지보수하기 쉬운 테스트 코드를 작성할 수 있게 해줍니다. 이 가이드를 마치면 버튼 클릭, 폼 제출, 비동기 데이터 로딩 등 실제 프로젝트에서 자주 마주치는 시나리오를 자신있게 테스트할 수 있게 됩니다.

기본 개념 설명

React Testing Library는 DOM Testing Library를 기반으로 하며, React 컴포넌트를 테스트하기 위한 가벼운 솔루션을 제공합니다. 핵심 철학은 “테스트가 소프트웨어 사용 방식과 유사할수록 더 많은 신뢰를 줄 수 있다”는 것입니다. 이는 state나 props 같은 내부 구현을 직접 테스트하는 대신, 렌더링된 결과물과 사용자 상호작용을 테스트해야 함을 의미합니다.

주요 개념으로는 쿼리(Queries), 이벤트(Events), 비동기 처리(Async)가 있습니다. 쿼리는 getByText, getByRole 등으로 DOM 요소를 찾는 방법이며, fireEvent와 userEvent는 사용자 상호작용을 시뮬레이션합니다. waitFor와 findBy 쿼리는 비동기 작업을 처리합니다. 또한 Jest와 함께 사용되어 expect 매처로 검증을 수행하며, @testing-library/jest-dom을 통해 toBeInTheDocument, toHaveTextContent 같은 편리한 매처를 추가로 사용할 수 있습니다.

단계별 구현 가이드

1단계: 환경 설정

Create React App으로 생성된 프로젝트는 이미 React Testing Library가 설정되어 있습니다. 기존 프로젝트에 추가하려면 다음 패키지를 설치하세요:

npm install --save-dev @testing-library/react @testing-library/jest-dom @testing-library/user-event

setupTests.js 파일을 생성하여 jest-dom을 import합니다:

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

2단계: 첫 번째 테스트 작성

간단한 Button 컴포넌트부터 시작해봅시다. 먼저 테스트할 컴포넌트를 만듭니다:

// Button.jsx
export default function Button({ onClick, children }) {
  return (
    
  );
}

이제 테스트 파일을 작성합니다:

// Button.test.jsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Button from './Button';

test('버튼이 텍스트를 렌더링한다', () => {
  render();
  expect(screen.getByText('클릭하세요')).toBeInTheDocument();
});

test('클릭 시 핸들러가 호출된다', async () => {
  const handleClick = jest.fn();
  const user = userEvent.setup();
  
  render();
  await user.click(screen.getByText('클릭'));
  
  expect(handleClick).toHaveBeenCalledTimes(1);
});

3단계: 쿼리 우선순위 이해하기

React Testing Library는 접근성을 고려한 쿼리 우선순위를 권장합니다:

  • getByRole: 가장 권장되는 방법 (버튼, 링크, 제목 등)
  • getByLabelText: 폼 요소에 적합
  • getByPlaceholderText: 입력 필드
  • getByText: 텍스트 콘텐츠
  • getByTestId: 최후의 수단

4단계: 폼 테스트하기

실제 애플리케이션에서 자주 사용되는 폼 컴포넌트를 테스트하는 방법입니다:

// LoginForm.jsx
import { useState } from 'react';

export default function LoginForm({ onSubmit }) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    onSubmit({ email, password });
  };

  return (
    
setEmail(e.target.value)} /> setPassword(e.target.value)} />
); }

5단계: 비동기 작업 테스트

API 호출이나 타이머 같은 비동기 작업을 테스트할 때는 waitFor나 findBy 쿼리를 사용합니다:

test('데이터 로딩 후 표시', async () => {
  render();
  
  // 로딩 중 표시 확인
  expect(screen.getByText('로딩 중...')).toBeInTheDocument();
  
  // 데이터가 로드될 때까지 대기
  const items = await screen.findAllByRole('listitem');
  expect(items).toHaveLength(3);
});

실제 코드 예제와 설명

React Testing Library로 테스트 작성하기의 실전 예제로 TodoList 컴포넌트를 완전히 테스트해봅시다:

// TodoList.test.jsx
import { render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import TodoList from './TodoList';

describe('TodoList 컴포넌트', () => {
  test('새로운 할 일을 추가할 수 있다', async () => {
    const user = userEvent.setup();
    render();
    
    const input = screen.getByRole('textbox', { name: /할 일 입력/i });
    const addButton = screen.getByRole('button', { name: /추가/i });
    
    await user.type(input, '장보기');
    await user.click(addButton);
    
    expect(screen.getByText('장보기')).toBeInTheDocument();
    expect(input).toHaveValue('');
  });
  
  test('할 일을 완료 처리할 수 있다', async () => {
    const user = userEvent.setup();
    render();
    
    const checkbox = screen.getByRole('checkbox', { name: /청소하기/i });
    await user.click(checkbox);
    
    expect(checkbox).toBeChecked();
  });
  
  test('할 일을 삭제할 수 있다', async () => {
    const user = userEvent.setup();
    render();
    
    const deleteButton = screen.getByRole('button', { name: /삭제/i });
    await user.click(deleteButton);
    
    expect(screen.queryByText('운동하기')).not.toBeInTheDocument();
  });
  
  test('완료된 할 일 개수를 표시한다', () => {
    const todos = [
      { id: 1, text: '할 일 1', done: true },
      { id: 2, text: '할 일 2', done: false },
      { id: 3, text: '할 일 3', done: true }
    ];
    
    render();
    expect(screen.getByText(/2개 중 2개 완료/i)).toBeInTheDocument();
  });
});

이 예제에서는 userEvent.setup()으로 사용자 이벤트를 초기화하고, getByRole로 접근성 좋은 쿼리를 사용하며, async/await로 비동기 이벤트를 처리하는 모범 사례를 보여줍니다.

고급 활용 방법

커스텀 렌더 함수 만들기

Context Provider나 Router로 감싸야 하는 컴포넌트를 테스트할 때 커스텀 렌더 함수를 만들면 편리합니다:

// test-utils.jsx
import { render } from '@testing-library/react';
import { ThemeProvider } from './ThemeContext';

export function renderWithTheme(ui, options) {
  return render(
    {ui},
    options
  );
}

// 사용 예
import { screen } from '@testing-library/react';
import { renderWithTheme } from './test-utils';

test('테마가 적용된 컴포넌트', () => {
  renderWithTheme();
  expect(screen.getByText('Hello')).toHaveStyle({ color: 'blue' });
});

MSW로 API 모킹하기

Mock Service Worker(MSW)를 사용하면 실제 HTTP 요청을 인터셉트하여 테스트할 수 있습니다:

import { rest } from 'msw';
import { setupServer } from 'msw/node';

const server = setupServer(
  rest.get('/api/users', (req, res, ctx) => {
    return res(ctx.json([{ id: 1, name: '홍길동' }]));
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

마무리 및 추가 학습 자료

React Testing Library로 테스트 작성하기를 마스터하면 더 안정적이고 유지보수하기 쉬운 React 애플리케이션을 만들 수 있습니다. 핵심은 구현 세부사항이 아닌 사용자 관점에서 테스트하는 것입니다. 지속적인 연습을 통해 테스트 작성 속도와 품질을 모두 향상시킬 수 있습니다.

추가 학습 자료:

  • 공식 문서: testing-library.com/react
  • Kent C. Dodds의 Testing JavaScript 강의
  • Common mistakes with React Testing Library 가이드
  • React Testing Library 치트시트

이제 여러분의 프로젝트에 직접 테스트를 작성해보세요. 작은 컴포넌트부터 시작하여 점차 복잡한 시나리오로 확장해 나가면 자연스럽게 테스트 작성 능력이 향상될 것입니다!

📚 함께 읽으면 좋은 글

1

React Router 실전 사용법 – 초보자도 쉽게 따라하는 완벽 가이드

📂 React 튜토리얼
📅 2025. 10. 15.
🎯 React Router 실전 사용법

2

React 컴포넌트 설계 패턴 – 초보자도 쉽게 따라하는 완벽 가이드

📂 React 튜토리얼
📅 2025. 10. 14.
🎯 React 컴포넌트 설계 패턴

3

React Hooks 실전 활용 가이드 – 초보자도 쉽게 따라하는 완벽 가이드

📂 React 튜토리얼
📅 2025. 10. 8.
🎯 React Hooks 실전 활용 가이드

4

React 컴포넌트 설계 패턴 – 초보자도 쉽게 따라하는 완벽 가이드

📂 React 튜토리얼
📅 2025. 10. 6.
🎯 React 컴포넌트 설계 패턴

5

React 성능 최적화 완벽 가이드 – 초보자도 쉽게 따라하는 완벽 가이드

📂 React 튜토리얼
📅 2025. 10. 5.
🎯 React 성능 최적화 완벽 가이드

💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!

📢 이 글이 도움되셨나요? 공유해주세요!

여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨

🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏

💬 여러분의 소중한 의견을 들려주세요!

이 글을 읽고 새롭게 알게 된 정보가 있다면 공유해주세요!

💡
유용한 정보 공유

궁금한 점 질문

🤝
경험담 나누기

👍
의견 표현하기

⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨

🔔 블로그 구독하고 최신 글을 받아보세요!

📚
다양한 주제
17개 카테고리

정기 업데이트
하루 3회 발행

🎯
실용적 정보
바로 적용 가능

💡
최신 트렌드
2025년 기준

🌟 React 튜토리얼부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨

📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!

답글 남기기