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

개발 에러 해결 가이드 - FixLog 노트

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

1. 도입 – 학습 목표 및 필요성

React Testing Library로 테스트 작성하기는 현대 React 애플리케이션 개발에서 필수적인 스킬입니다. 이 튜토리얼에서는 사용자 중심의 테스트 작성 방법을 배우고, 실제 프로젝트에 바로 적용할 수 있는 실전 예제를 다룹니다. React Testing Library는 Enzyme과 달리 컴포넌트의 구현 세부사항이 아닌 사용자 경험에 초점을 맞춰 테스트를 작성하도록 설계되었습니다. 이를 통해 리팩토링에 강하고, 유지보수가 쉬운 테스트 코드를 만들 수 있습니다. 버그를 사전에 방지하고, 코드 품질을 향상시키며, 자신감 있게 리팩토링할 수 있는 능력을 키워보세요.

2. React Testing Library 기본 개념 설명

React Testing Library는 Kent C. Dodds가 개발한 테스팅 라이브러리로, “사용자가 애플리케이션을 사용하는 방식”으로 테스트를 작성하는 철학을 따릅니다. 핵심 원칙은 다음과 같습니다:

  • 사용자 중심 테스트: state나 props가 아닌 DOM에 렌더링된 결과를 테스트합니다.
  • 접근성 우선: getByRole, getByLabelText 등 접근성 기반 쿼리를 권장합니다.
  • 구현 세부사항 회피: 컴포넌트 내부 로직이 아닌 사용자가 보는 결과를 검증합니다.

주요 API는 render(컴포넌트 렌더링), screen(렌더링된 요소 접근), fireEvent/userEvent(사용자 상호작용 시뮬레이션), waitFor(비동기 작업 대기)로 구성됩니다. Jest와 함께 사용하면 강력한 테스트 환경을 구축할 수 있습니다. 이러한 도구들은 Create React App에 기본으로 포함되어 있어 별도 설정 없이 바로 시작할 수 있습니다.

3. 단계별 구현 가이드

3.1 설치 및 설정

먼저 프로젝트에 필요한 패키지를 설치합니다:

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

Create React App을 사용하지 않는다면 Jest 설정 파일(jest.config.js)을 생성합니다:

module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['/src/setupTests.js'],
  moduleNameMapper: {
    '\\.(css|less|scss)$': 'identity-obj-proxy',
  },
};

setupTests.js 파일을 생성하여 전역 설정을 추가합니다:

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

3.2 첫 번째 테스트 작성

간단한 버튼 컴포넌트부터 시작합니다. 테스트 파일은 컴포넌트 파일과 같은 디렉토리에 *.test.js 또는 *.spec.js 형식으로 생성합니다:

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

test('버튼이 올바른 텍스트로 렌더링되는지 확인', () => {
  render();
  const buttonElement = screen.getByRole('button', { name: /클릭하세요/i });
  expect(buttonElement).toBeInTheDocument();
});

3.3 쿼리 우선순위 이해

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

  1. getByRole: 가장 권장되는 방법 (button, heading, textbox 등)
  2. getByLabelText: 폼 요소에 적합
  3. getByPlaceholderText: placeholder가 있는 input 요소
  4. getByText: 텍스트 콘텐츠로 검색
  5. getByTestId: 최후의 수단 (data-testid 속성 사용)

3.4 사용자 상호작용 테스트

userEvent는 fireEvent보다 실제 사용자 행동에 가까운 이벤트를 시뮬레이션합니다:

test('버튼 클릭 시 카운터 증가', async () => {
  const user = userEvent.setup();
  render();
  
  const button = screen.getByRole('button', { name: /증가/i });
  const counter = screen.getByText(/카운트: 0/i);
  
  await user.click(button);
  expect(screen.getByText(/카운트: 1/i)).toBeInTheDocument();
});

4. 실제 코드 예제와 설명

React Testing Library로 테스트 작성하기의 실전 예제로 로그인 폼을 테스트해보겠습니다:

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

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

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!email || !password) {
      setError('모든 필드를 입력해주세요');
      return;
    }
    onSubmit({ email, password });
  };

  return (
    
setEmail(e.target.value)} />
setPassword(e.target.value)} />
{error &&
{error}
}
); } export default LoginForm;
// LoginForm.test.js
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import LoginForm from './LoginForm';

test('사용자가 로그인 폼을 작성하고 제출할 수 있다', async () => {
  const user = userEvent.setup();
  const mockSubmit = jest.fn();
  
  render();
  
  // 폼 요소 찾기
  const emailInput = screen.getByLabelText(/이메일/i);
  const passwordInput = screen.getByLabelText(/비밀번호/i);
  const submitButton = screen.getByRole('button', { name: /로그인/i });
  
  // 사용자 입력 시뮬레이션
  await user.type(emailInput, 'test@example.com');
  await user.type(passwordInput, 'password123');
  await user.click(submitButton);
  
  // 결과 검증
  expect(mockSubmit).toHaveBeenCalledWith({
    email: 'test@example.com',
    password: 'password123',
  });
  expect(mockSubmit).toHaveBeenCalledTimes(1);
});

test('빈 폼 제출 시 에러 메시지 표시', async () => {
  const user = userEvent.setup();
  const mockSubmit = jest.fn();
  
  render();
  
  const submitButton = screen.getByRole('button', { name: /로그인/i });
  await user.click(submitButton);
  
  // 에러 메시지 확인
  expect(screen.getByRole('alert')).toHaveTextContent('모든 필드를 입력해주세요');
  expect(mockSubmit).not.toHaveBeenCalled();
});

5. 고급 활용 방법

5.1 비동기 작업 테스트

API 호출과 같은 비동기 작업은 waitFor, findBy 쿼리를 사용합니다:

test('API에서 데이터를 가져와 표시한다', async () => {
  render();
  
  // 로딩 상태 확인
  expect(screen.getByText(/로딩중/i)).toBeInTheDocument();
  
  // 데이터가 로드될 때까지 대기
  const userItems = await screen.findAllByRole('listitem');
  expect(userItems).toHaveLength(3);
});

5.2 Mock Service Worker(MSW) 활용

실제 API 호출을 모킹하여 독립적인 테스트를 작성합니다:

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());

5.3 커스텀 렌더 함수

Redux, Router 등 Provider가 필요한 컴포넌트를 위한 커스텀 렌더 함수를 만듭니다:

function renderWithProviders(ui, options) {
  return render(
    
      {ui}
    ,
    options
  );
}

6. 마무리 및 추가 학습 자료

React Testing Library로 테스트 작성하기를 통해 사용자 중심의 견고한 테스트를 작성하는 방법을 배웠습니다. 핵심은 구현 세부사항이 아닌 사용자 경험을 테스트하는 것입니다. 지속적인 연습을 통해 테스트 커버리지를 높이고 버그 없는 안정적인 애플리케이션을 만들어보세요.

추가 학습 자료:

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

이제 여러분의 프로젝트에 테스트를 적용하고, 더 나은 코드 품질을 경험해보세요!

📚 함께 읽으면 좋은 글

1

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

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

2

React Context API 마스터하기 – 초보자도 쉽게 따라하는 완벽 가이드

📂 React 튜토리얼
📅 2025. 10. 31.
🎯 React Context API 마스터하기

3

React Context API 마스터하기 – 초보자도 쉽게 따라하는 완벽 가이드

📂 React 튜토리얼
📅 2025. 10. 30.
🎯 React Context API 마스터하기

4

React Context API 마스터하기 – 초보자도 쉽게 따라하는 완벽 가이드

📂 React 튜토리얼
📅 2025. 10. 30.
🎯 React Context API 마스터하기

5

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

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

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

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

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


📘 페이스북


🐦 트위터


✈️ 텔레그램

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

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

이 글에서 가장 도움이 된 부분은 어떤 것인가요?

💡
유용한 정보 공유

궁금한 점 질문

🤝
경험담 나누기

👍
의견 표현하기

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

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

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

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

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

💡
최신 트렌드
2025년 기준

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

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

📱 전체 버전 보기