인프런의 "따라하며 배우는 리액트 테스트"를 듣고 정리해 봤다.
테스트를 하는 이유
- 더 안정적인 어플리케이션을 만들기 위해
- 디버깅 시간 단축 - 테스팅 환경이 구축되어 있다면 자동화된 유닛 테스팅으로 특정 버그를 쉽게 찾아 낼 수 있다.
- 재설계 시간 단축, 추가 구현 용이
사용 툴
React Testing Library
React 컴포넌트 테스트용 라이브러리 - 사용자 입장의 테스트, 행위 주도 테스트 (click, type 등)
DOM Testing Library 위에 구축
주요 API
- render
- DOM에 컴포넌트 렌더링, 인자로 렌더링할 컴포넌트
- 리턴 값으로 RTL에서 제공하는 쿼리 함수, 기타 유틸 함수를 담고 있는 개체를 리턴
- 해당 쿼리, 유틸 함수는 소스 코드가 복잡할 경우 비추천, 대신 screen객체를 사용하기
- screen
- RTL의 모든 쿼리 함수를 가지고 있는 객체
쿼리 함수
페이지에서 엘리먼트를 찾기 위해 RTL이 제공하는 함수
크게 3종류(get
, find
, query
)가 있다.
getBy...
: 쿼리에 대해 일치하는 엘리먼트 리턴, 일치하는 엘리먼트 없거나 2개 이상이면 오류 발생시킴 (2개 이상일 시getAllBy
사용)queryBy...
: 쿼리에 대해 일치하는 엘리먼트 반환, 없으면 null 반환, 존재하지 않는 요소 assertion시 유용, 2개 이상일 시 오류 발생 (2개 이상일 시queryAllBy
사용)findBy...
: 쿼리에 대해 일치하는 엘리먼트가 발견되면 resolve되는 Promise 반환, 엘리먼트가 발견되지 않거나 기본 제한 시간인 1000ms 이후 2개 이상의 엘리먼트가 발견되면 reject된다. (2개 이상일 시findAllBy
사용) findBy = getBy + waitFor
RTL 공식 쿼리 사용 가이드
- 모든 요소에 접근 가능한 쿼리 - visual/ mouse 뿐만 아니라 보조 기술(점자 등) 사용자의 경험까지 고려
getByRole
: 접근성 트리에 나타나는 모든 엘리먼트에 사용할 수 있다.name
옵션을 통해 접근 가능한 이름으로 엘리먼트를 찾을 수 있다. ex)getByRole('button', {name: /제출/i})
getByLabelText
: 폼 관련해서 사용하기 좋다. 보통 사용자가 웹사이트 폼을 사용할 때 라벨 텍스트를 보고 엘리먼트를 찾기 때문이다.getByPlaceholderText
: 폼에서 라벨 텍스트가 없을 경우 사용getByText
: 폼을 제외하고, 사용자는 요소들을 찾을 때 텍스트를 본다. 유저와 상호작용하지 않는div
,span
,p
getByDisplayValue
: 폼에 데이터가 입력되어 있는 경우 폼 요소의 현재 값을 기준으로 찾는다.
- Semantic 쿼리 - 태그 속성등으로 엘리먼트를 찾는 쿼리 / 브라우저, 보조 기술에 따라 속성들이 매우 달라지기 때문에 안 쓰는게 좋다.
getByAltText
: altText 속성으로 찾기 (img
,area
,input
등)getByTitle
: title 속성으로 찾기, 스크린 리더로 읽히지 않는 경우가 많다.
- Test Id
getByTestId
: 사용자가 볼 수 없다. 위에 쿼리들로 못 찾는 경우에만 쓰도록 하자
fireEvent 보다는 userEvent를 사용하자
userEvent는 fireEvent를 사용해서 만들어졌다.
각 엘리먼트와 상호작용할 때 해당 엘리먼트 타입에 맞는 적절한 반응(사용자 행위와 비슷)을 보여준다.
ex) 버튼 클릭시 fireEvent는 버튼 focus X , userEvent는 버튼 focus O
Jest
페북이 만든 테스팅 프레임워크
단위 테스트용
파일 구조
- describe - 관련 테스트 그룹화
- it - 개별 테스트, 각 테스트를 문장으로 설명, 문장은 상세하게 어떤 테스트인지 말해주는게 좋다.
- expect: 값을 테스트, matcher와 함께 사용
- matcher: 여러 방법으로 값을 테스트
- toBe
- toBeCalledWith 등등
환경 설정
ESLint 설정
// eslintrc.js
{
"plugins": [
"testing-library",
"jest-dom"
],
"extends": [
"react-app",
"react-app/jest",
"plugin:testing-library/react",
"plugin:jest-dom/recommended"
]
}
JEST 설정
// jest.config.js
module.exports = {
preset: 'ts-jest', // jest로 TS 테스팅이 가능하게 해준다.
rootDir: '../..',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/config/jest/setupTests.js'],
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'ts-jest',
},
moduleNameMapper: {
'@/(.*)': '<rootDir>/src/$1', // webpack alias 사용하려면 똑같이 맞춰야 module import 에러 발생하지 않음
},
}
'프론트엔드 > 테스트' 카테고리의 다른 글
React 테스트 방법 (0) | 2023.05.07 |
---|---|
TDD (0) | 2023.05.07 |