
react-testing-libraryr에서는 Enzyme 과 달리 모든 테스트를 DOM 위주로 진행합니다. 그리고, 컴포넌트의 props 나 state 를 조회하는 일은 없습니다. 컴포넌트를 리팩토링하게 될 때에는, 주로 내부 구조 및 네이밍은 많이 바뀔 수 있어도 실제 작동 방식은 크게 바뀌지 않습니다. react-testing-library는 이 점을 중요시 여겨서, 컴포넌트의 기능이 똑같이 작동한다면 컴포넌트의 내부 구현 방식이 많이 바뀌어도 테스트가 실패하지 않도록 설계되었습니다. 추가적으로, Enzyme 은 엄청나게 다양한 기능을 제공하는 반면, react-testing-library 에는 정말 필요한 기능들만 지원을 해줘서 매우 가볍고, 개발자들이 일관성 있고 좋은 관습을 따르는 테스트 코드를 작성 할 수 있도록 유도해줍니다.둘다 유닛테스트
Enzyme :구현 주도 테스트 (Implementation Driven Test)
React Testing Library :행위 주도 테스트 (Behavior Driven Test
react-testing-library 주요 API

위에 비추천, 아래 추천





FireEvent,userEvent: 이벤트 핸들러 처리에대한 테스트를 해야할떄 사용한다고 보면 될것 같다

jest는 FaceBook에 의해서 만들어진 테스팅 프레임 워크입니다. 최소한의 설정으로 동작하며 Test Case 를 만들어서 어플리케이션 코 드가 잘 돌아가는지 확인해줍니다. 단위 (Unit) 테스트를 위해서 이용합니다.내가 작성한 코드가 제대로 동작하는지 확인할 때 사용한다. 여러가지 상황들을 설정하고, 그 상황에 맞는 결과가 나오는지 테스트코드 파일을 찾아서 자동으로 테스트 해준다.
jest가 테스트파일 찾는법

jest파일구조,사용법


첫번째 테스트 코드 사례
App.js
import { useState } from "react";
function App() {
const [counter, setCounter] = useState(0);
const [disabled, setDisabled] = useState(false);
return (
<div className="App">
<header className="App-header">
<h3 data-testid="counter">{counter}</h3> {/*test id 작성법: data-testid */}
<div>
<button
data-testid="minus-button"
onClick={() => setCounter((count) => count - 1)}
disabled={disabled}
>
-
</button>
<button
data-testid="plus-button"
onClick={() => setCounter((count) => count + 1)}
disabled={disabled}
>
+
</button>
</div>
<div>
<button
data-testid="on/off-button"
style={{ backgroundColor: "blue" }}
onClick={() => setDisabled((prev) => !prev)}
>
on/off
</button>
</div>
</header>
</div>
);
}
export default App;
App.test.js
import { render, screen, fireEvent } from "@testing-library/react";
import App from './App';
test('the counter starts at 0', () => {
render(<App />);//render = dom의 컴포넌트를 렌더하는 함수(인자로 react컴포넌트가 들어감)
const counterElement = screen.getByTestId("counter")//screen = 원하는 element에 접근해주는 객체 //getByTestId(query함수)=요소를 찾기위한 방법
expect(counterElement).toHaveTextContent(0) //jest의 expect와 matcher
});
//마이너스 버튼 테스트
test("minus button has correct text", () => {
render(<App />);
const minusButtonElement = screen.getByTestId("minus-button");
expect(minusButtonElement).toHaveTextContent("-");
});
//플러스 버튼 테스트
test("plus button has correct text", () => {
render(<App />);
const plusButtonElement = screen.getByTestId("plus-button");
expect(plusButtonElement).toHaveTextContent("+");
});
//유저가 발생시키는 액션이벤트에 대한 테스트는 fireEvent으로 진행
//플러스 버튼 클릭스 count증가 했나 테스트
test("When the + button is pressed, the counter changes to 1", () => {
render(<App />);
const buttonElement = screen.getByTestId("plus-button");
fireEvent.click(buttonElement);
const counterElement = screen.getByTestId("counter");
expect(counterElement).toHaveTextContent(1);
});
//유저가 발생시키는 액션이벤트에 대한 테스트는 fireEvent으로 진행
//플러스 버튼 클릭스 count감소 했나 테스트
test("When the - button is pressed, the counter changes to -1", () => {
render(<App />);
const buttonElement = screen.getByTestId("minus-button");
fireEvent.click(buttonElement);
const counterElement = screen.getByTestId("counter");
expect(counterElement).toHaveTextContent(-1);
});
//버튼 css요소 테스트
test("on/off button has blue color", () => {
render(<App />);
const buttonElement = screen.getByTestId("on/off-button");
expect(buttonElement).toHaveStyle({ backgroundColor: "blue" });
});
// on/off버튼 클릭시 -,+ 버튼 작동,불작동 테스트
test("Prevent the -,+ button from being pressed when the on/off button is cliecked", () => {
render(<App />);
const onOffButtonElement = screen.getByTestId("on/off-button");
fireEvent.click(onOffButtonElement);
const plusButtonElement = screen.getByTestId("plus-button");
const minusButtonElement = screen.getByTestId("minus-button");
expect(plusButtonElement).toBeDisabled();
expect(minusButtonElement).toBeDisabled();
});
//test.only = 따른테스트케이스 제외하고 이것만 테스트
//test.skip = 해당테스트만 제외하고 테스트
//https://testing-library.com/docs/queries/about/#priority 쿼리우선순위
두번째 테스트 코드 사례
import React, { useState, useContext } from "react";
const SummaryPage = () => {
const [checked, setChecked] = useState(false);
return (
<div>
<form}>
<input type="checkbox" id="confirm-checkbox" checked={checked} onChange={(e) => setChecked(e.target.checked)} />
<label htmlFor="confirm-checkbox">주문하려는 것을 확인하셨나요?</label>
<br />
<button disabled={!checked} type="submit">
주문 확인
</button>
</form>
</div>
);
};
export default SummaryPage;
summaryPage.js
import SummaryPage from "../SummaryPage";
import { render, screen } from "../../../test-utils";
test("checkbox and button", () => {
render(<SummaryPage />);
//체크박스 내용,노체크 확인
const checkbox = screen.getByRole("checkbox", {
name: "주문하려는 것을 확인하셨나요?",
});
expect(checkbox.checked).toEqual(false); //체크박스 초기상태는 false
//확인버튼 내용,비활성화 확인
const confirmButton = screen.getByRole("button", { name: "주문 확인" });
expect(confirmButton.disabled).toBeTruthy(); //checkbox 체크안할시 주문확인버튼 비활성화
});
//웬만하면 우선순위 높은getByRole query이용
summaryPage.test
matcher 목록:
testing-library/jest-dom: Custom jest matchers to test the state of the DOM (github.com)
GitHub - testing-library/jest-dom: Custom jest matchers to test the state of the DOM
:owl: Custom jest matchers to test the state of the DOM - GitHub - testing-library/jest-dom: Custom jest matchers to test the state of the DOM
github.com
Using Matchers · Jest (jestjs.io)
Using Matchers · Jest
Jest uses "matchers" to let you test values in different ways. This document will introduce some commonly used matchers. For the full list, see the expect API doc.
jestjs.io
testing library 공식사이트:
Firing Events | Testing Library (testing-library.com)
Firing Events | Testing Library
Note
testing-library.com
'TDD' 카테고리의 다른 글
Mock Service Worker (0) | 2022.03.30 |
---|---|
react-testing-library query 함수 (0) | 2022.03.24 |