프론트엔드 단위 테스트 마스터하기: 입문부터 고급까지
2025-04-29 03:23:16javascriptreactnextjsfrontend
프론트엔드 단위 테스트의 중요성과 개념
프론트엔드 개발은 사용자의 직접적인 경험에 큰 영향을 미치는 분야입니다. 코드의 안정성은 사용자 경험을 좌우할 수 있으며, 이를 위해 단위 테스트는 필수적입니다. 단위 테스트는 코드의 각 단위가 기대한 대로 작동하는지 검증하는 과정입니다. 각 함수, 컴포넌트, 모듈을 독립적으로 테스트하여 버그가 발생하기 전에 포착합니다.
왜 단위 테스트를 해야 할까?
- 초기에 버그를 발견: 제품의 생산 환경에 도달하기 전에 문제를 해결합니다. 이를 통해 시간과 비용을 절약할 수 있습니다.
- 코드 품질 향상: 코드를 여러 번 검토하고 테스트하면서 더욱 명확하고 유지 보수 가능한 코드를 작성하게 됩니다.
- 안전한 리팩토링: 기존 코드의 기능을 변형하거나 개선해도, 테스트를 통해 그 기능이 실패하지 않았음을 보장받을 수 있습니다.
- 예상 동작 문서화: 코드가 의도한 대로 작동하는지를 확인하며, 이는 또한 현업자들 간의 커뮤니케이션에도 유용합니다.
초급: 첫 번째 테스트 환경 설정과 테스트 작성
Step 1: 테스트 프레임워크 선택하기
프론트엔드 개발 환경에서 활용할 수 있는 여러 테스트 프레임워크가 있습니다. 가장 인기 있는 방법은 다음과 같습니다:
- Jest: React, Vue 및 일반적인 JavaScript 사용 시 추천합니다.
- Mocha + Chai: 설정이 유연하지만 추가 설정이 필요할 수 있습니다.
- Vitest: Vite와 호환성이 뛰어나고 빠릅니다.
Step 2: Jest 설치하기
먼저, Jest를 개발 종속성으로 설치합니다.
npm install --save-dev jest
그리고 package.json 파일에 다음과 같이 테스트 스크립트를 추가합니다.
"scripts": {
"test": "jest"
}
Step 3: 첫 번째 테스트 작성하기
간단한 함수를 테스트해 보겠습니다.
sum.js
function sum(a, b) {
return a + b;
}
module.exports = sum;
sum.test.js
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
이제 테스트를 실행합니다:
npm test
축하합니다! 첫 번째 유닛 테스트를 작성했습니다.
중급: React 컴포넌트 테스트하기
Step 1: 리액트 테스트 도구 설치
npm install --save-dev @testing-library/react @testing-library/jest-dom
Step 2: 리액트 컴포넌트 테스트
Button.js
import React from 'react';
function Button({ onClick, children }) {
return <button onClick={onClick}>{children}</button>;
}
export default Button;
Button.test.js
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import Button from './Button';
test('Button calls onClick when clicked', () => {
const handleClick = jest.fn();
const { getByText } = render(<Button onClick={handleClick}>Click Me</Button>);
fireEvent.click(getByText('Click Me'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
Step 3: 컴포넌트 렌더링 테스트
test('Button renders correctly', () => {
const { getByText } = render(<Button>Submit</Button>);
expect(getByText('Submit')).toBeInTheDocument();
});
고급: Mocking & 비동기 테스트
API 호출 모킹: Fetch, Axios
fetchData.js
async function fetchData(url) {
const response = await fetch(url);
return response.json();
}
fetchData.test.js
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ data: 'Mocked data' }),
})
);
test('fetchData returns mocked data', async () => {
const data = await fetchData('https://api.example.com');
expect(data).toEqual({ data: 'Mocked data' });
expect(fetch).toHaveBeenCalledWith('https://api.example.com');
});
커스텀 훅 테스트하기
useCounter.js
import { useState } from 'react';
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(count + 1);
return { count, increment };
}
useCounter.test.js
import { renderHook, act } from '@testing-library/react-hooks';
import useCounter from './useCounter';
test('useCounter increments count', () => {
const { result } = renderHook(() => useCounter(0));
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
효과적인 단위 테스트를 위한 베스트 프랙티스
- ✔ 동작을 테스트하고 구현을 테스트하지 말 것
- ✔ 테스트를 작고 집중적으로 유지
- ✔ 설명적인 테스트 이름 사용
- ✔ 외부 종속성을 모킹
- ✔ CI/CD 파이프라인에서 테스트 실행
결론
단위 테스트는 연습을 통해 개선되며, 작은 부분부터 시작해 중요한 논리부터 테스트해 나가세요. 점차 테스트 커버리지를 확장하는 것이 중요합니다. 더 많은 정보는 다음 우리가 제공한 링크를 참고하세요.
유용한 링크
테스트에 대한 문의가 있거나 도전 과제가 있다면, 댓글로 함께 이야기해 봐요! 🚀