AAA 패턴(Arrange / Act / Assert)
1. Arrange: 테스트 전 준비사항들을 구성한다. state, service를 준비하고 라이브러리들을 Mocking하는 단계이다. 테스트할 element를 렌더링하는 과정이 포함된다. 앞서 설정과 해지 패턴에서 알아본 beforeEach와 afterEach를 작성한다.
2. Act: User의 액션에 따른 테스트 코드를 실행한다.
3. Assert: Act로 인해 변경되거나 구성되는 값들을 검증하는 과정이다. element의 값을 검증, element의 생성과 소멸 상태값의 변경 시간에 따라 변화하는 값을 감지한다. 사용자의 의도적인 인터랙션에 의해 변화되는 모든 값을 검증하는 과정이다.
AAA 패턴 예
describe('<Counter /> component', () => {
test('click increase work', () => {
// Arrange
render(<Counter />)
const count = screen.getByRole('count')
const increaseCount = screen.getByRole('button', { name: '+' })
// Act
fireEvent.click(increaseCount)
// Assert
expect(count.textContent).toBe('1')
})
})
UI 인터랙션 단위 검증
- fireEvent:
- async method: 비동기 메소드 인터랙션 단위 검증: 비동기 함수의 경우 일반적인 테스트는 실패한다. expect 하는 시점에 아직 동작이 완료되지 않았기 때문이다.
비동기 메소드 검증 예제
구현코드
import { useDebounce } from '@/hooks/useDebounce';
import { FC, useEffect, useState } from 'react'
type Props = {
toggled?: boolean
}
export const Switch: FC<Props> = ({ toggled }: Props) => {
...
const debouncedValue = useDebounce<boolean>(internal, 30)
...
return (
<label role='switch'>
<input type="checkbox" checked={checked} onChange={callback} />
<span></span>
{checked ? 'on' : 'off'}
</label>
);
}
export default Switch;
useDebounce hook 내부에 setTimeout()을 사용하여 일종의 비동기 처리가 될 수 있다.
유닛 테스트의 의도된 결과값이 나오지 않을 수 있다.
import Switch from "@/pages/switch";
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
describe('<Switch />', () => {
it('click input, and check it turned on', async () => {
render(<Switch />);
fireEvent.click(screen.getByRole('checkbox'))
expect(screen.getByRole('switch', { name: /on/i })).toBeInTheDocument();
});
on 변경된 값은 30ms 이후에 동작하는 수정사항이므로 expect가 수행되는 시점에서는 비동기의 동작이 끝나지 않아 스크린에서 찾을 수 없다.
이런 경우에는 async method를 사용하면 된다.
// 1. findByRole : 자체적으로 진행해주는 비동기 처리
expect(await screen.findByRole('switch', { name: /on/i })).toBeInTheDocument();
// 2. waitFor: waitFor의 함수 콜백이용하여 기존에 받았던 코드 동작이 모두 끝난 이후에 마저 진행이 되도록 처리
expect(await waitFor(() => screen.getByRole('switch', { name: /on/i }))).toBeInTheDocument();
시간이 지난 후 보여지는 것을 검증하기 위한 코드
1. findBy ~ : 비동기 처리 로직, return 값이 Promise이다. Promise가 기다려지고 난 이후에 동작 검증이 수행된다.
2. waitFor : 비동기 처리를 못하는 함수들에 대해 비동기 완료까지 대기
추가 예시) 돔에서 제거되는 로직 검증
test('remove from DOM', async() => {
await waitForElementToBeRemoved(() => queryByText('hello'));
})
callback function을 이용, 해당 element가 mutation되어 사라 질 때까지 기다리다가 이후에 resolve 시키는 식으로 진행이 된다.
복잡한 컴포넌트를 테스트할 때에는 컴포넌트의 목적과 동작에 맞춰 컴포넌트 별로, 동작 별로 분리 시켜서 테스트를 작성한다.
[참고]
패스트캠퍼스 강의 (100가지 시나리오로 학습하는 프론트엔드 : 5년 이상 경험을 초압축한 실전 문제 해결 패키지) 를 기반으로 작성하였고, 추가 서치 내용을 정리하였습니다.
'개발공부 > React' 카테고리의 다른 글
[React] CRA 없이 리액트 앱 만들기: 목적과 프로젝트 세팅 (4) | 2024.10.12 |
---|---|
[React] 테스팅 패턴 - 외부 모듈의 Mocking을 이용한 검증 (0) | 2024.07.31 |
[React] 테스팅 패턴 - 모의 데이터를 이용하여 검증 (0) | 2024.07.27 |
[React] 테스팅 패턴 - Rendering 검증 (0) | 2024.07.21 |
[React] 테스팅 패턴 - 설정과 해지 (0) | 2024.07.01 |