티스토리 뷰
TDD 원칙대로 세팅
TDD 원칙대로라면 기능 코드를 추가하기 전에 테스트를 작성해야 합니다.
이번 예제에서는 App.js에서 할 거라 App.js를 비워주겠습니다.
📜 App.js 파일
function App() {
return <div />;
}
export default App;
1. 테스트하려는 내용들 세팅
전역 테스트 메서드인 test에는 총 2개의 인자가 들어간다고 했었습니다. 첫 번째 인자에는 테스트의 문자열 설명, 두 번째 인자에는 테스트 함수입니다. 우선 내가 테스트하고자 하는 내용들을 모두 적어서 세팅해봅시다.
저는 버튼에 올바르게 초기 색상이 적용되었는지, 클릭 시 파란색으로 바뀌는지 기능 테스트까지 해보려고 합니다.
📜 App.test.js 파일
test('button has correct initial color', () => {});
test('button turns blue when clicked', () => {});
테스트할 대상은 모두 적어주었고, 이제 테스트 방식에 해당하는 두 번째 인자로 테스트 함수를 작성해 봅시다.
2. 테스트 함수 작성
(1) 렌더링할 대상을 render 함수 안에 적는다.
render(<App />);
(2) 살펴보려는 요소를 찾는다.
여기에서는 렌더링을 통해 생성된 가상 DOM에 엑세스할 수 있는 전역 객체 screen을 사용합니다. 각 요소들은 역할을 가지고 있는데, 이때 역할은 아래 사이트에서 살펴볼 수 있습니다.
render(<App />);
const colorButton = screen.getByRole('button', { name: 'Change to blue' });
위 코드에서 name은 표시되는 텍스트를 의미합니다.
(3) Matcher를 통해 테스트할 내용을 작성한다.
이제 버튼의 색상도 테스트해야 하는데, 이를 위해 jest-dom에 있는 다른 옵션을 살펴보겠습니다.
아래는 Github의 jest-dom 페이지입니다. 여기에서 커스텀 matcher들이 무엇이 있는지를 확인할 수 있습니다.
이 중에서도 toHaveStyle을 사용해 버튼의 배경색이 무엇인지 확인하려고 합니다.
render(<App />);
const colorButton = screen.getByRole('button', { name: 'Change to blue' });
expect(colorButton).toHaveStyle({ backgroundColor: 'red' });
여기까지하면 테스트 하나 작성을 완료한 것입니다.
3. 테스트 진행 상황 확인 → 레드 부분 🔴
npm test를 입력하여 확인해봅시다. 우리는 테스트 코드만 작성하고 실제 컴포넌트는 구현하지 않았으니 당연히 실패가 뜨는 것이 당연하다고 생각하고 실행해봅시다.
예상대로 테스트 결과가 나왔습니다. 여기까지 레드-그린 테스트에서 레드 부분은 성공적으로 마친 것입니다 :)
4. 실제 구현 하기 → 그린 부분 🟢
App.js 파일로 가서 테스트가 성공할 수 있도록 실제 구현을 하기 고쳐봅시다.
📜 App.js 파일
function App() {
return (
<div>
<button style={{ backgroundColor: 'red' }}>Change to blue</button>
</div>
);
}
export default App;
다시 테스트를 진행해보니 테스트에 성공한 것을 확인할 수 있었습니다.
➕ Roles 디버깅을 위한 logRoles
위 예시 코드에서 내가 작업하는 버튼의 역할이 있는 걸 몰랐다고 한다면 이 경우 사용할 수 있는 디버깅 도구가 있습니다.
아래 사이트를 통해 logRoles 메서드에 관한 내용을 확인할 수 있습니다.
📜 App.test.js 파일
import { logRoles, render, screen } from '@testing-library/react';
import App from './App';
test('button has correct initial color', () => {
const { container } = render(<App />);
logRoles(container);
const colorButton = screen.getByRole('button', { name: 'Change to blue' });
expect(colorButton).toHaveStyle({ backgroundColor: 'red' });
});
위와 같이 작성하고 실행하면 logRoles의 출력값을 볼 수 있습니다.
내용을 보게 되면, 해당 컴포넌트에 있는 역할이 출력되고 그 이름을 알 수 있습니다.
아까 우리가 테스트할 내용을 2개 작성해 두었는데 나머지 하나가 버튼을 클릭했을 때 파란색으로 바뀌는지였습니다. 이 부분에 대해서도 순서에 맞게 작성해보겠습니다.
이번에는 테스트할 때 '버튼이 클릭되는 것'을 테스트해야 하니까 버튼을 클릭을 해야하는데 이때 fireEvent 라는 객체를 통해 이루어지도록 할 것입니다. 또한 버튼이 눌린 후 텍스트가 Change to red로 바뀐 경우도 expect할 것입니다 :)
📜 App.test.js 파일
test('button turns blue when clicked', () => {
render(<App />);
const colorButton = screen.getByRole('button', { name: 'Change to blue' });
// 버튼을 클릭
fireEvent.click(colorButton);
// 배경 색이 파란색으로 바뀌는 것을 expect
expect(colorButton).toHaveStyle({ backgroundColor: 'blue' });
// 눌렸으므로 버튼 텍스트도 Change to red가 되는 것을 expect
expect(colorButton).toHaveTextContent('Change to red');
});
위 코드를 작성하고 테스팅을 시작하면 아직 구현을 안 해놓았으니 당연히 실패가 뜰 것입니다. 레드 과정이죠 ! 🔴
아직 구현을 하지 않아서 발생하는 당연한 문제입니다.
이제 구현을 해봅시다! 그린 과정입니다 🟢
📜 App.js 파일
import { useState } from 'react';
function App() {
const [color, setColor] = useState('red');
const onClickRedBtn = () => {
setColor('blue');
};
return (
<div>
<button style={{ backgroundColor: color }} onClick={onClickRedBtn}>
Change to {color === 'red' ? 'blue' : 'blue'}
</button>
</div>
);
}
export default App;
우리가 구현하고 싶었던 부분을 기능으로 구현해보았습니다. 그리고 테스트 한 결과는 다음과 같았습니다.
'프론트엔드 > React' 카테고리의 다른 글
[React] Virtual DOM과 ✨React 렌더링 동작 원리✨ with Fiber (2) | 2023.06.12 |
---|---|
[React] RTL의 screen 객체가 가진 쿼리 메서드(query Methods) (0) | 2023.06.07 |
[React] React Testing Library (RTL)에 대해 알아보자 (0) | 2023.06.06 |
[React] Watch 모드와 테스트가 작동하는 방식 (0) | 2023.06.06 |
[React] jest-dom으로 처음 테스트해보기 & 테스팅 라이브러리 구문 소개 (0) | 2023.06.06 |
- Total
- Today
- Yesterday
- JSP
- 프론트엔드
- frontend
- react
- 스타일 컴포넌트 styled-components
- jest
- 프론트엔드 기초
- rtl
- 리액트
- TypeScript
- styled-components
- HTML
- 딥러닝
- next.js
- 자바스크립트
- 머신러닝
- 파이썬
- 자바스크립트 기초
- 프로젝트 회고
- 자바
- 타입스크립트
- testing
- 디프만
- 인프런
- 리액트 훅
- 프론트엔드 공부
- Python
- 데이터분석
- react-query
- CSS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |