바쁘다는 핑계로 테스트 코드 도입, 말만 1년째...
but, 혼자 공부해서 세미나 열어주겠어.
npm install --save-dev jest
package.json에 테스트 스크립트 추가
{
"scripts": {
"test": "jest"
}
}
vsCode를 사용하면 확장프로그램으로 jest를 깔면 npm test 말고,
더 편한 ui로 테스트를 실행해볼 수 있다.
기본적으로 알아야 할 주요 함수는 describe
, test
(또는 it
), expect
입니다.
describe
와 test
describe: 관련된 테스트를 그룹화할 때 사용합니다.
test 또는 it: 개별 테스트를 정의합니다.
//간단한 제목
describe('간단한 숫자 계산', () => {
//테스트 상세 설명
test('2 더하기 2는 4', () => {
expect(2 + 2).toBe(4);
});
test('2 곱하기 3은 6', () => {
expect(2 * 3).toBe(6);
});
});
test : 일반적으로 명확하게 “테스트를 정의한다”는 의미를 전달할 때 많이 사용됩니다.
it은 : “이것은 ~~한다”는 방식으로 자연스럽게 문장처럼 읽히도록 작성할 수 있어, 테스트의 의도를 보다 가독성 있게 표현할 때 유용합니다.
라고 지피티가 말해줬는데 뭔말인지 모르겠으니, 더 정리해보자.
// 두 방법은 완전히 동일하게 작성
test('2 더하기 2는 4', () => {
expect(2 + 2).toBe(4);
});
it('2 더하기 2는 4', () => {
expect(2 + 2).toBe(4);
});
it("should do this thing", () => {});
it("should do the other thing", () => {});
test("if it does the other thing", () => {});
test("if it does the other thing", () => {});
근데 그냥 개취라서 맘에 드는거 쓰면 될 듯
const calculator = {
add: (a, b) => a + b,
};
test('add 함수가 호출되었는지 확인', () => {
const spy = jest.spyOn(calculator, 'add');
calculator.add(1, 2);
expect(spy).toHaveBeenCalled(); // 함수가 호출되었는지 확인
expect(spy).toHaveBeenCalledWith(1, 2); // 특정 인자로 호출되었는지 확인
spy.mockRestore(); // 스파이 함수 복원
});
const fetchData = (callback) => {
setTimeout(() => {
callback('data received');
}, 1000);
};
test('콜백 함수가 올바르게 호출되었는지 확인', () => {
const mockCallback = jest.fn();
fetchData(mockCallback);
expect(mockCallback).not.toHaveBeenCalled(); // setTimeout 때문에 즉시 호출되지 않음
jest.runAllTimers(); // 모든 타이머가 실행되도록 함
expect(mockCallback).toHaveBeenCalledWith('data received');
});
어떤 .tsx 페이지에 라우터를 이동할 버튼이 use-navigate로 경로를 이동한다고 할 때를 예시로 들어보면
NavigationButton.jsx
import React from 'react';
import { useNavigate } from 'react-router-dom';
const NavigationButton = () => {
const navigate = useNavigate();
const handleClick = () => {
navigate('/new-page');
};
return <button onClick={handleClick}>Go to New Page</button>;
};
export default NavigationButton;
테스트코드.jsx
// src/components/NavigationButton.test.js
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { useNavigate } from 'react-router-dom';
import NavigationButton from './NavigationButton';
// useNavigate 훅을 Mock 처리
jest.mock('react-router-dom', () => ({
useNavigate: jest.fn(),
}));
describe('네비 버튼 컴포넌트 ~~~', () => {
test('누르면 /page 로 이동하게끔 ~~ ', () => {
// Mock 함수 생성
const mockNavigate = jest.fn();
// Mock 함수 반환 설정
useNavigate.mockReturnValue(mockNavigate);
// 컴포넌트 렌더링
const { getByText } = render(<NavigationButton />);
// 버튼 클릭
fireEvent.click(getByText('Go to New Page'));
// navigate 함수가 '/page'로 호출되었는지 검증
expect(mockNavigate).toHaveBeenCalledWith('/new-page');
});
});
개별 기능
테스트모듈이나 컴포넌트 간의 상호작용
테스트시나리오에 기반한 전체 흐름
테스트일단 이렇게 간단하게 (안 간단한가 ,,) 알아보았는데,
React에서 Jest 외에도 여러 다른 테스팅 라이브러리를 사용할 수 있지만, 처음 접해본 Jest는 생각보다 훨씬 유용하다는 인상을 받았다.
또한, 테스트 우선순위를 명확히 정하고 중요 기능부터 차근차근 검증해 나가면서, 코드 품질을 한층 높일 수 있다는 점이 좋았다. Jest를 통해 더 안정적이고 유지보수하기 쉬운 코드를 작성하는 데 도움이 될 것 같네용. 굿!
테스트를 통해 코드의 신뢰성을 높이고, 개발 과정에서의 불확실성을 줄이는 것은 장기적으로 더 나은 소프트웨어 개발을 위한 중요한 과정임을 다시 한번 느꼈다.
테스트코드가 몸에 밸 수 있을 때까지 연습!