TDD
코드 작성 전에 테스트코드를 작성하고
코드 작성 후에 통과 시키기
왜 TDD?
테스트를 작성하는것이 프로세스에 자연스럽게 통합되도록
원하는 대로 동작하는지를 확인할 수 있음
jest와 rtl
rtl은 가상 돔을 렌더링하고 요소를 검색하고 가상 돔과 상호작용하는 역할
그리고 여기서 테스트 러너가 필요한데 그게 제스트
에러가 있어야 걸리는 구조라 빈 테스트면 통과됨, throw Error 해도 걸림
유닛 테스트
코드의 한 부분을 테스트, 다른 유닛과의 상호작용을 고려하지 않음
코드(함수)의 테스트는 가능해도 사용자 관점의 테스트를 뜻하지는 않음
리팩토링 시 동일한 동작이라도 테스트에서 걸릴 수 있음
통합 테스트
여러 유닛의 상호작용을 테스트
기능 테스트
일반적인 함수가 아닌 소프트웨어의 동작을 테스트(좀 더 전체적인 느낌)
코드가 아닌 행동(동작)을 테스트하는 것
디버깅이 어려울 수 있음
RTL은 기능 테스트 식으로 테스트하기를 권장
E2E테스트
실제 브라우저가 필요하고 서버가 필요
단언문에서 실패하면 다음 테스트를 수행하지 않고 바로 멈춤
테스트 코드 예시
import { render, screen, fireEvent } from "@testing-library/react";
test("button has correct initial color", () => {
render(<App />);
const colorButton = screen.getByRole("button", {
name: "Change to Midnight Blue",
});
expect(colorButton).toHaveStyle({
backgroundColor: "MediumVioletRed",
});
fireEvent.click(colorButton);
expect(colorButton).toHaveStyle({ backgroundColor: "MidnightBlue" });
expect(colorButton).toHaveTextContent("Change to Medium Violet Red");
});
버튼 컴포넌트를 테스트한다고 치면 어떤 클래스네임을 가진 버튼을 선택하는 방식이 아니라 어떤 텍스트를 가진 버튼(getByRole
로 기능을 확인)인지를 체크하여 동작시킨다.
최초 색상,텍스트 확인 - 클릭(`fireEvent`) - 변경된 색상, 텍스트 확인
이런 구조라서 시나리오를 쓰듯 테스트 할 수 있다.
fireEvent와 user-event의 차이
- fireEvent는 DOM의 이벤트를 디스패치
- user-event는 모든 상호작용을 시뮬레이션(좀 더 사용자 관점), promise를 반환
user-event
import userEvent from "@testing-library/user-event";
test("...", async () => {
const user = userEvent.setup();
await user.click(element);
});
user-event
를 사용하기 위해서는 setup
메서드를 사용해 유저 객체를 만들고
객체 내부의 이벤트 메서드를 사용해야 한다.
그리고 이 이벤트들은 promise를 반환하기 때문에 await을 꼭 써주어야 한다(당연히 테스트의 콜백 함수도 async 함수여야 함)
getBy와 queryBy의 차이점
getBy
는 일치하는 요소가 없거나 여러개인 경우 오류를 발생시킨다.
반면에 queryBy
는 일치하는 요소가 없으면 null을 반환한다. 특정 이벤트(호버)가 발생했을 때만 나타나는 팝업같은 요소를 테스트할 때 사용한다.
'공부' 카테고리의 다른 글
[jest/rtl] 강의 기록(msw, 비동기) (0) | 2023.07.10 |
---|---|
[TS] 이펙티브 타입스크립트 #26 (0) | 2023.04.02 |
[TS] 이펙티브 타입스크립트 #20, #21 (0) | 2023.03.12 |
[TS] 이펙티브 타입스크립트 #19 (0) | 2023.03.11 |
[TS] 이펙티브 타입스크립트 #14 (0) | 2023.02.26 |
댓글