이미지 로딩 중...
CodeDeck AI
2025. 11. 8. · 2 Views
Testing 기초부터 심화까지 완벽 가이드
소프트웨어 테스팅의 기본 개념부터 고급 기법까지 단계별로 학습합니다. Unit Test, Integration Test, Mock, TDD 등 실무에 필요한 모든 테스팅 기법을 다룹니다.
들어가며
이 글에서는 Testing 기초부터 심화까지 완벽 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- 첫_번째_유닛_테스트
- Matcher_활용하기
- 비동기_코드_테스트
- Mock_함수_사용
- Setup과_Teardown
- 모듈_Mocking
- 스냅샷_테스팅
- 예외_처리_테스트
- TDD_실습_예제
- 통합_테스트_기본
- 테스트_커버리지_확인
- Describe로_그룹화
1. 첫_번째_유닛_테스트
개요
가장 기본적인 유닛 테스트 작성법입니다. Jest를 사용하여 함수의 결과값을 검증합니다.
코드 예제
function add(a, b) {
return a + b;
}
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
설명
test 함수로 테스트 케이스를 정의하고, expect로 예상 결과를 검증합니다. toBe는 값이 정확히 일치하는지 확인합니다.
2. Matcher_활용하기
개요
Jest의 다양한 Matcher를 사용하여 여러 조건을 테스트합니다.
코드 예제
test('다양한 matcher 사용', () => {
expect(2 + 2).toBe(4);
expect('Hello').toMatch(/ello/);
expect([1, 2, 3]).toContain(2);
expect({ name: 'John' }).toHaveProperty('name');
expect(null).toBeNull();
});
설명
toBe는 정확한 일치, toMatch는 정규식 매칭, toContain은 배열 포함 여부, toHaveProperty는 객체 속성 검증에 사용됩니다.
3. 비동기_코드_테스트
개요
async/await를 사용하여 비동기 함수를 테스트합니다.
코드 예제
async function fetchData() {
return Promise.resolve('data');
}
test('비동기 데이터 가져오기', async () => {
const data = await fetchData();
expect(data).toBe('data');
});
설명
비동기 함수 테스트 시 test 함수를 async로 선언하고, await로 결과를 기다린 후 검증합니다.
4. Mock_함수_사용
개요
Mock 함수를 생성하여 함수 호출 여부와 인자를 검증합니다.
코드 예제
const mockFn = jest.fn(x => x * 2);
test('mock 함수 테스트', () => {
mockFn(2);
expect(mockFn).toHaveBeenCalledWith(2);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn(3)).toBe(6);
});
설명
jest.fn()으로 Mock 함수를 생성하고, 호출 횟수와 전달된 인자를 검증할 수 있습니다.
5. Setup과_Teardown
개요
각 테스트 전후로 실행되는 설정 및 정리 코드를 작성합니다.
코드 예제
let database;
beforeEach(() => {
database = { users: [] };
});
afterEach(() => {
database = null;
});
test('사용자 추가', () => {
database.users.push('John');
expect(database.users).toHaveLength(1);
});
설명
beforeEach는 각 테스트 전에, afterEach는 각 테스트 후에 실행되어 테스트 환경을 초기화합니다.
6. 모듈_Mocking
개요
외부 모듈을 Mock으로 대체하여 독립적인 테스트를 수행합니다.
코드 예제
jest.mock('./api');
const api = require('./api');
test('API 호출 mock', async () => {
api.fetchUser.mockResolvedValue({ name: 'John' });
const user = await api.fetchUser(1);
expect(user.name).toBe('John');
});
설명
jest.mock()으로 모듈을 Mock으로 대체하고, mockResolvedValue로 반환값을 설정합니다.
7. 스냅샷_테스팅
개요
컴포넌트나 객체의 출력을 스냅샷으로 저장하여 변경사항을 추적합니다.
코드 예제
function formatUser(user) {
return `${user.name} (${user.email})`;
}
test('사용자 포맷 스냅샷', () => {
const user = { name: 'John', email: 'john@test.com' };
expect(formatUser(user)).toMatchSnapshot();
});
설명
toMatchSnapshot()은 첫 실행 시 결과를 저장하고, 이후 실행에서 변경사항을 감지합니다.
8. 예외_처리_테스트
개요
함수가 올바르게 에러를 발생시키는지 검증합니다.
코드 예제
function divide(a, b) {
if (b === 0) throw new Error('0으로 나눌 수 없습니다');
return a / b;
}
test('0으로 나누기 에러', () => {
expect(() => divide(10, 0)).toThrow('0으로 나눌 수 없습니다');
});
설명
에러를 발생시키는 함수는 화살표 함수로 감싸서 전달하고, toThrow로 에러 메시지를 검증합니다.
9. TDD_실습_예제
개요
테스트를 먼저 작성하고 구현하는 TDD(Test Driven Development) 방식입니다.
코드 예제
// 1. 테스트 먼저 작성
test('배열에서 중복 제거', () => {
expect(removeDuplicates([1, 2, 2, 3])).toEqual([1, 2, 3]);
});
// 2. 구현
function removeDuplicates(arr) {
return [...new Set(arr)];
}
설명
실패하는 테스트를 먼저 작성한 후, 테스트를 통과하는 최소한의 코드를 구현하는 방식입니다.
10. 통합_테스트_기본
개요
여러 모듈이 함께 동작하는지 확인하는 통합 테스트입니다.
코드 예제
class UserService {
constructor(db) { this.db = db; }
async createUser(name) {
return this.db.insert({ name, createdAt: new Date() });
}
}
test('사용자 생성 통합 테스트', async () => {
const mockDb = { insert: jest.fn().mockResolvedValue({ id: 1 }) };
const service = new UserService(mockDb);
const user = await service.createUser('John');
expect(mockDb.insert).toHaveBeenCalled();
expect(user).toHaveProperty('id');
});
설명
여러 컴포넌트의 상호작용을 테스트하며, 의존성은 Mock으로 대체하여 제어 가능하게 만듭니다.
11. 테스트_커버리지_확인
개요
코드의 어느 부분이 테스트되었는지 확인하는 커버리지 측정입니다.
코드 예제
// package.json
{
"scripts": {
"test": "jest",
"test:coverage": "jest --coverage"
}
}
// 터미널에서 실행
// npm run test:coverage
설명
--coverage 옵션으로 테스트 커버리지를 측정하여 어떤 코드가 테스트되지 않았는지 확인할 수 있습니다.
12. Describe로_그룹화
개요
관련된 테스트들을 describe 블록으로 그룹화하여 구조화합니다.
코드 예제
describe('Calculator', () => {
describe('덧셈', () => {
test('양수 더하기', () => {
expect(1 + 1).toBe(2);
});
});
describe('뺄셈', () => {
test('양수 빼기', () => {
expect(5 - 3).toBe(2);
});
});
});
설명
describe 블록으로 테스트를 논리적으로 그룹화하여 가독성을 높이고 테스트 결과를 구조적으로 확인할 수 있습니다.
마치며
이번 글에서는 Testing 기초부터 심화까지 완벽 가이드에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#Testing #Jest #UnitTest #Mock #TDD