"사용자가 소프트웨어를 사용하는 방식과 유사하게 테스트하라"는 철학 아래, 컴포넌트의 렌더링부터 복잡한 비동기 로직까지 검증하는 실전 테스팅 기법임
키워드: RTL(React Testing Library), AAA 패턴, User Event, Mocking(jest.fn), Async Testing
리액트 테스팅 라이브러리(RTL)의 최우선 가치는 내부 구현(State, Props 명칭 등)이 아닌 사용자의 관점을 검증하는 것입니다.
❖ 핵심 원칙:
모든 테스트 코드는 가독성과 유지보수를 위해 3단계 구조를 따릅니다.
render()로 가상 DOM에 띄움.userEvent 활용).expect()로 확인.getByText)가장 기본적인 텍스트 렌더링 확인 단계입니다. describe로 관련 테스트를 그룹화합니다.
describe('Greeting component', () => {
test('renders "Hello World" as a text', () => {
render(<Greeting />); // Arrange
const helloWorldElement = screen.getByText('Hello World!'); // Act & Assert
expect(helloWorldElement).toBeInTheDocument();
});
});
getByRole & userEvent)버튼 클릭 시 UI가 변하는지 테스트합니다. userEvent는 실제 브라우저의 상호작용(포커스, 클릭 등)을 더 정밀하게 흉내 냅니다.
test('버튼 클릭 시 "Changed!" 문구가 나타나는지 확인', () => {
render(<Greeting />);
// 1. 역할(Role)로 버튼 찾기
const buttonElement = screen.getByRole('button');
// 2. 사용자의 실제 클릭 동작 수행
userEvent.click(buttonElement);
// 3. 변경된 UI 검증
const outputElement = screen.getByText('Changed!');
expect(outputElement).toBeInTheDocument();
});
queryBy)특정 요소가 화면에 없어야 함을 검증할 때는 getBy를 쓰면 안 됩니다. 요소를 찾지 못하는 순간 에러를 던져 테스트가 중단되기 때문입니다.
queryByText: 요소를 찾지 못하면 에러 대신 null을 반환합니다.expect(...).toBeNull()과 함께 사용하여 특정 UI가 사라졌음을 안전하게 확인합니다.Mocking)API 호출처럼 시간이 걸리는 작업은 실제 네트워크를 타지 않도록 jest.fn()으로 가짜 함수를 만들어 대체(Mocking)합니다.
test('성공 시 포스트 목록을 렌더링함', async () => {
// 1. Mocking: 실제 fetch를 가짜 함수로 대체하여 외부 의존성 제거
window.fetch = jest.fn();
window.fetch.mockResolvedValueOnce({
json: async () => [{ id: 'p1', title: 'First post' }],
});
render(<Async />);
// 2. 비동기 대기: findAllByRole
// find로 시작하는 메서드는 요소가 나타날 때까지 기다리며 Promise를 반환함
const listItemElements = await screen.findAllByRole('listitem');
// 3. 결과 검증
expect(listItemElements).not.toHaveLength(0);
});
상황에 맞는 쿼리(Query)를 선택하는 것이 테스트의 견고함을 결정합니다. 단순히 요소를 찾는 것을 넘어, 테스트의 의도에 맞는 접두사를 사용하는 것이 중요합니다.
| 메서드 접두사 | 특징 | 용도 |
|---|---|---|
| getBy... | 요소를 즉시 찾음. 없으면 즉시 에러 발생 | 일반적인 요소 존재 확인 (가장 기본적이고 많이 쓰임) |
| queryBy... | 요소를 찾지 못하면 에러 대신 null 반환 | 특정 요소가 존재하지 않음을 안전하게 확인할 때 |
| findBy... | 요소를 찾을 때까지 기다림 (Promise 반환) | 비동기 데이터 로딩 후 화면에 나타나는 요소를 확인할 때 |
getByRole을 최우선으로 사용하세요. 이는 시각 장애인이 스크린 리더를 사용하는 방식과 유사하여 접근성까지 함께 테스트할 수 있습니다.getBy는 요소를 찾지 못할 때 전체 DOM 구조를 에러 메시지로 보여주기 때문에 디버깅에 매우 유리합니다.findBy는 기본적으로 1000ms(1초) 동안 요소를 기다립니다. API 응답 속도에 따라 이 시간은 조절 가능합니다.