Skip to content

리액트 테스트 관련 참고 문서 저장소 (Jest, React-Testing-Library) 🧑‍💻

Notifications You must be signed in to change notification settings

ssi02014/react-test-reference-documentation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 

Repository files navigation

💻 리액트 테스트 참고 문서 저장소

  • 해당 저장소는 Jest, React-Testing-Library를 통해 테스트를 진행하면서 자주 확인하게되는 쿼리 우선순위, 역할의 종류,Screen Query, jest matchers, fireEvent(userEvent) 이벤트 종류 등을 알아보기 쉽게, 공식 문서를 찾아보기 쉽게 정리한 저장소입니다.
  • 오탈자 및 수정이 필요한 내용은 pull request, issue 등 자유롭게 남겨주시면 반영하겠습니다.

🌟 Contributors

contributors


📄 목차

  1. React Testing Library
  2. 대표적인 테스트 유형
  3. RTL과 접근성
  4. 쿼리 우선순위
  5. 역할의 종류
  6. Screen Query
  7. Jest Matchers
  8. fireEvent
  9. userEvent

  • Others
  1. React Testing Library, jest-dom ESLint Setting
  2. React Testing Library에서 자주하는 실수 및 해결


React Testing Library

React Testing Library 사용 이유 ❓

  • RTL(React Testing Library)는 테스트를 위한 가상 DOM을 생성하고 생성한 DOM과 상호 작용하기 위한 유틸리티도 제공한다. 예를 들어, DOM에서 요소를 찾거나 클릭과 같이 요소와 상호 작용할 수 있다. 또한, 브라우저 없이 테스트도 가능하다.

주의 사항 ❗️

  • RTL을 처음 접할 때면 RTL을 Jest의 대안으로 혼동하는 경우가 더러 있다.
  • 두 도구는 React 내에서 테스트를 진행할 때 같이 사용되기에 상호 보완 관계라고 볼 수 있다. (엄밀히 말하자면, RTL이 Jest를 포함하는 구조)
  • 전반적으로 Jest를 통해 기능 테스트를 진행할 수는 있지만, React의 컴포넌트를 렌더링하고 테스트하기 위해서는 몇 가지 기능이 더 필요하다.
    • Jest - 자체적인 test runnertest util 제공
    • RTL - Jest + React 컴포넌트 test util 제공

테스트 유형

  • 유닛(Unit) 테스트

    • 보통 함수나 별개의 React 컴포넌트 코드의 한 유닛 혹은 단위를 테스트한다.
    • 유닛 테스트의 특징은 다른 코드의 유닛과 상호 작용하는 것은 테스트하지 않는다.
  • 통합(Intergration) 테스트

    • 여러 유닛이 함께 동작하는 방식을 테스트해서 유닛 간의 상호 작용을 테스트하는 것이다. 예를 들어 컴포넌트 간의 상호 작용을 테스트 하거나 마이크로 서비스 간의 상호 작용을 테스트한다.
  • 기능(functional) 테스트

    • 소프트웨어의 특정 기능을 테스트하는 것이다.
    • 헷갈릴 수 있는게 function은 프로그래밍 언어에서 입력값을 취하고 출력을 제공하는 소프트웨어 단위(Unit)의 함수를 의미할 수도 있고, 소프트웨어의 동작을 의미할 수도 있는데 이 경우에는 특정 코드 함수가 아닌 소프트웨어 동작에 해당한다. 즉, 기능 테스트의 의미는 코드가 아닌 동작을 테스트하는 것이다.
  • 인수(Acceptance) 테스트 혹은 End to End (E2E) 테스트

    • 실제 사용자 환경에서 사용자의 입장으로 테스트를 수행하는 것을 의미한다.
    • 실제 브라우저가 필요하고 애플리케이션이 연결된 서버가 필요하다. 보통 CypressSelenium과 같은 도구가 필요하다. 참고로 이 테스트는 RTL을 위해 설계된 테스트는 아니다.

RTL은 유닛 테스트보다 기능 테스트를 권장 한다.

  • 즉, 실제 사용자 경험과 유사한 방식의 테스트를 작성할 것을 권장하는 것이다.
    • 예를 들어 <div>Hello World</div>라는 코드가 있다면, RTL은 div 태그를 사용하는지보다 Hello World 메시지가 브라우저에 노출이 되는지 파악하는 것을 더 중요하다고 본다.
  • 기능에 초점을 맞춘 테스트 방식은 신뢰도를 높임과 동시에 코드 리팩토링 시 테스트 코드 수정 빈도를 줄일 수 있습니다.

RTL과 접근성

  • RTL은 우리의 웹사이트가 어떻게 사용되는지 최대한 가깝게 테스트를 작성할 수 있도록 장려하는 메서드와 유틸리티를 제공한다.
  • 테스트 할 때 실제 사용자가 쓰는 것처럼 해야 하는데 여기에 스크린 리더와 같은 접근성 인터페이스도 포함된다.
  • 접근성을 준수하기위해 어떤 쿼리를 우선순위로 사용해야되는 지는 아래를 참고하자.

쿼리 우선순위

  • 아래 문서를 통해 가상 DOM에서 요소를 찾을 때 어떤 쿼리를 우선 순위로 사용해야 하는지 참고하자.
  • 쿼리 우선순위(priority)

역할의 종류

  • 쿼리 우선순위(priority)를 봤으면 *ByRole을 사용하는 방법 즉, 역할을 통해 요소를 찾을 수 있고, 실제로 스크린 리더에서 액세스 할 수 있다. 따라서 접근성을 보장하기때문에 요소를 찾을때 가장 선호되는 방법이다.
  • *ByRole은 여러 역할을 활용 할 수 있는데 이는 아래 문서들을 확인하고 참고하자.

  • 참고로 role 속성을 사용해서 div와 같은 요소에도 특정 역할을 추가할 수 있다. 코드에는 단순히 role=""처럼 속성을 추가하면 된다.
  • 일반적으로 스크린 리더에서 테스트 요소를 찾을 수 없으면, 그건 우리의 앱이 스크린 리더에 친화적이지 않은 거고 접근성에서 안좋다는 의미이다 ❗️
  • 아래 예제는 role 속성을 통해 역할을 부여한 예제이다.
<div role="textbox"></div>
const textbox = screen.getByRole("textbox");

expect(textbox).toBeEmptyDOMElement();

Screen Query

  • Screen Query는 페이지에서 요소를 찾기 위해 Testing Library가 제공하는 방법입니다.
  • 아래 문서를 통해 Screen Query에대해 알아보자.
  • Screen Query
<button type="submit" disabled>submit</button>
import { screen } from "@testing-library/react";

// getByRole screen query 사용
const button = screen.getByRole("button", {
  name: "submit",
});

expect(button).toBeDisabled();

Jest Matchers

  • Jest는 matcher를 사용하여 다양한 방식으로 값을 테스트할 수 있습니다.
  • 아래 문서를 통해 다양한 Jest의 Matcher를 알아보자
  • Jest Matchers
<input type="text" />
const input = screen.getByRole("textbox");

expect(input).toBeInTheDocument(); // toBeInTheDocument matcher 사용

fireEvent

  • RTL - fireEvent 공식 문서
  • fireEvent는 쿼리 함수로 선택된 영역을 대상으로 특정 이벤트를 발생시키기 위한 이벤트 함수들을 담고 있다.
  • fireEvent는 아래와 같이 기본적인 포맷을 갖고 있다.
fireEvent(node: HTMLElement, event: Event)
import { render, screen, fireEvent } from "@testing-library/react";

test("버튼을 클릭하면 배경색이 빨간색으로 변경한다.", () => {
  render(<MyComponent />);
  const button = screen.getByRole("button", {
    name: "button",
  });

  fireEvent.click(colorButton);
  expect(colorButton).toHaveStyle({ backgroundColor: "red" });
});

userEvent

  • RTL - userEvent 공식 문서
  • RTL - fireEvent 공식 문서를 보면 실제로 fireEvent도 좋지만 대부분의 경우 userEvent를 사용해야된다고 언급된다.
  • 일반적으로 fireEvent에 비해 userEvent가 사용자 이벤트를 더욱 완전하고 현실적인 방식으로 시뮬레이션 한다.
  • 쉽게 말하면, 사용자가 실제 웹사이트를 이용하는 플로우대로 시뮬레이션한다.
Most projects have a few use cases for fireEvent, but the majority of the time you should probably use @testing-library/user-event.
  • userEvent에대해서는 아래 문서를 통해 자세히 알아보자.
  • userEvent

Jest에서 it과 test의 차이

  • jest에서 it은 test의 별칭이며, 따라서 기능이 완전히 동일하다.
  • 하지만, 이름이 다르기 때문에 테스트 이름 작성하는 부분에서 약간의 차이가 있다. 테스트 이름 가독성에 맞게 어느 것을 선택할지 결정하면 된다.
test("if it does the other thing", () => {});
test("if it does the other thing", () => {});
it("should do this thing", () => {});
it("should do the other thing", () => {});

About

리액트 테스트 관련 참고 문서 저장소 (Jest, React-Testing-Library) 🧑‍💻

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published