프로그래밍/Next.js

[Next.js14 강의] 29강 - 테스트 작성 및 유닛 테스트

월횽 2024. 9. 26. 06:30
728x90
반응형
SMALL

안녕하세요! 그레이 해커 월횽입니다. 이번 강의에서는 테스트 작성의 중요성을 이해하고, Next.js에서 유닛 테스트를 작성하는 방법을 학습합니다. Jest, React Testing Library 등의 도구를 사용하여 컴포넌트와 함수가 의도한 대로 동작하는지 검증하는 테스트를 작성합니다.

 

 

1. 테스트의 중요성

 

1-1. 테스트란 무엇인가?

테스트는 코드가 예상대로 동작하는지 자동으로 검증하는 절차입니다. 특히 유닛 테스트는 개별 함수나 컴포넌트가 정확하게 작동하는지를 확인하는 데 중점을 둡니다.

 

1-2. 테스트의 이점

· 코드 품질 향상: 버그를 사전에 발견할 수 있어 코드의 신뢰성을 높일 수 있습니다.
· 유지보수 용이: 코드 변경 시 기존 기능이 의도한 대로 작동하는지 확인할 수 있어, 리팩토링과 기능 추가가 용이합니다.
· 안전성 보장: 테스트가 충분하면 배포 후 문제 발생 가능성을 줄일 수 있습니다.

 

 

2. 테스트 도구 선택

Next.js에서는 Jest와 React Testing Library를 많이 사용합니다. Jest는 테스트 러너로, 다양한 테스트를 실행하고 결과를 출력하는 역할을 하며, React Testing Library는 React 컴포넌트의 DOM을 쉽게 테스트할 수 있도록 도와줍니다.

반응형

2-1. Jest 설치

프로젝트에 Jest를 설치하려면 다음 명령어를 실행합니다.

npm install --save-dev jest

설치 후, 프로젝트 루트에 jest.config.js 파일을 생성하여 Jest 설정을 추가합니다.

module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['./jest.setup.js'],
};

 

 

2-2. React Testing Library 설치

React 컴포넌트를 테스트하려면 React Testing Library도 설치해야 합니다.

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

 

 

3. 유닛 테스트란 무엇인가?

 

3-1. 유닛 테스트 개요

유닛 테스트는 가장 작은 단위의 코드를 테스트하는 방법입니다. 주로 개별 함수나 컴포넌트를 테스트하며, 이들이 다양한 입력에서 올바른 결과를 반환하는지 확인합니다.

728x90

3-2. 유닛 테스트의 구조

유닛 테스트는 보통 AAA 패턴으로 작성됩니다.

· Arrange: 테스트에 필요한 데이터를 준비.
· Act: 테스트할 함수를 실행.
· Assert: 함수가 예상한 대로 동작하는지 검증.

test('adds 1 + 2 to equal 3', () => {
  // Arrange
  const a = 1;
  const b = 2;

  // Act
  const result = a + b;

  // Assert
  expect(result).toBe(3);
});

 

 

 

4. Jest로 유닛 테스트 작성하기

 

4-1. 간단한 함수 테스트

먼저 단순한 함수의 유닛 테스트를 작성해 봅시다.

SMALL
// math.js
export function add(a, b) {
  return a + b;
}

 

이제 add 함수를 테스트합니다.

// math.test.js
import { add } from './math';

test('1 + 2는 3이 되어야 한다', () => {
  expect(add(1, 2)).toBe(3);
});

test('음수 더하기 테스트', () => {
  expect(add(-1, -2)).toBe(-3);
});

 

 

4-2. 비동기 함수 테스트

비동기 코드는 테스트가 조금 더 복잡할 수 있습니다. Jest는 비동기 함수를 테스트할 때 async/await 또는 done 콜백을 사용할 수 있습니다.

// asyncFunction.js
export async function fetchData() {
  const response = await fetch('/api/data');
  const data = await response.json();
  return data;
}

// asyncFunction.test.js
import { fetchData } from './asyncFunction';

test('fetchData는 데이터를 반환해야 한다', async () => {
  const data = await fetchData();
  expect(data).toBeDefined();
});

 

 

5. React Testing Library로 컴포넌트 테스트하기

 

5-1. 컴포넌트 테스트

React Testing Library를 사용하여 React 컴포넌트를 테스트할 수 있습니다. 예를 들어, Button 컴포넌트를 테스트해 보겠습니다.

// Button.js
export default function Button({ onClick, children }) {
  return <button onClick={onClick}>{children}</button>;
}

 

컴포넌트의 클릭 이벤트를 테스트하려면

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

test('버튼 클릭 시 onClick 핸들러가 호출되어야 한다', () => {
  const handleClick = jest.fn();
  render(<Button onClick={handleClick}>클릭</Button>);

  const button = screen.getByText('클릭');
  fireEvent.click(button);

  expect(handleClick).toHaveBeenCalledTimes(1);
});

 

 

5-2. 상태 변화 테스트

useState나 useEffect를 사용하는 컴포넌트의 상태 변화도 쉽게 테스트할 수 있습니다.

// Counter.js
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <span>{count}</span>
      <button onClick={() => setCount(count + 1)}>증가</button>
    </div>
  );
}
// Counter.test.js
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';

test('카운터가 버튼 클릭 시 증가해야 한다', () => {
  render(<Counter />);

  const button = screen.getByText('증가');
  const counter = screen.getByText('0');

  fireEvent.click(button);
  
  expect(counter).toHaveTextContent('1');
});

 

 

 

6. 테스트 자동화 및 커버리지 확인

 

6-1. 테스트 실행

모든 테스트를 실행하려면 다음 명령어를 사용합니다.

npm test

 

 

6-2. 코드 커버리지 확인

Jest를 사용하면 코드 커버리지를 쉽게 확인할 수 있습니다. 커버리지를 활성화하려면 --coverage 플래그를 추가합니다.

npm test -- --coverage

 

테스트 후 커버리지 보고서를 확인하여 테스트되지 않은 코드를 파악할 수 있습니다.

 

 

7. Next.js에서의 테스트 전략

 

7-1. 페이지 및 API 테스트

Next.js는 페이지와 API 라우트를 지원하므로, 페이지 컴포넌트와 API 핸들러에 대한 테스트도 필요합니다. 페이지 컴포넌트는 React Testing Library로, API 핸들러는 Jest로 각각 테스트할 수 있습니다.

// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ name: 'Next.js' });
}
// pages/api/hello.test.js
import handler from './hello';

test('API는 200 상태 코드와 데이터를 반환해야 한다', () => {
  const req = {};
  const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };

  handler(req, res);

  expect(res.status).toHaveBeenCalledWith(200);
  expect(res.json).toHaveBeenCalledWith({ name: 'Next.js' });
});

 

 

이번 강의에서는 유닛 테스트와 React 컴포넌트 테스트를 중심으로 Next.js 애플리케이션에서 테스트를 작성하는 방법을 배웠습니다. 테스트는 코드의 품질을 보장하고, 리팩토링 시 발생할 수 있는 문제를 사전에 방지할 수 있는 중요한 과정입니다. 이를 통해 더 안전하고 신뢰성 있는 코드를 작성할 수 있습니다.

 

 

 

 

 

- 이전 수업 목록

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형
LIST