📌 React Testing Library 리액트에서 TDD 방식의 개발을 하기 위해서 테스팅 라이브러리를 사용해보자.
🎯 목적 1. 버그 캐치 테스트를 통해 예상치 못한 여러가지 버그들을 사전에 확인하기 용이하다.
2. 애플리케이션 신뢰도 향상 어떠한 근거로 이 애플리케이션이 제대로 동작하는지 근거를 뒷받침하고 이 근거에 대한 신뢰도를 높일 수 있다.
3. 질문 및 답변 시간 축소 누군가 어떤 컴포넌트가 어떻게 동작하는지 질문했을 때 그에대한 답변으로 이 테스트를 보여주기만 하면된다. 그럼으로 시간을 절약하고 유지보수성을 높일 수 있다.
4. 문서 역할 테스트라는 문서를 제공함으로서 2,3번의 장점을 가능하도록 한다.
💼 사용방법 우선 해당 라이브러리를 설치해준다.
1 2 3 4 5 npm install --save-dev @testing-library/react npm install --save-dev @testing-library/dom npm install --save-dev @testing-library/user-event
리액트 테스팅 라이브리러 와 DOM 테스트 라이브러리, 사용자 행동 테스트 라이브러리 를 설치하여 테스트 개발을 해보자.
🦖 Component 테스트 ✏️ 테스트 코드 작성하는 방법
테스트가 필요한 컴포넌트 렌더링
컴포넌트의 요소 탐색
요소와의 상호작용
어설션 테스트 결과와 기대 값이 일치하는 지 확인
우선 컴포넌트를 생성해주자.
📌 Tip 컴포넌트 생성 컴포넌트를 쉽게 생성하기 위해 yamoo9님이 제공해준 Tool 을 사용해보도록하자.
1 npx degit yamoo9/create-react-component create-react-component
1 2 3 4 5 6 7 8 { ... "scripts" : ..., "rc" : "node create-react-component create" , "rd" : "node create-react-component delete" }
1 2 npm run rc -- 컴포넌트_이름 // 컴포넌트 생성 npm run rd -- 컴포넌트_이름 // 컴포넌트 제거
ESLint 에서 테스팅 라이브러리를 사용하게되면 오류를 띄워주는데 이에 대한 Lint 경고를 꺼두자.
1 2 3 4 5 { "eslintConfig" : { ...} , "testing-library/no-debugging-utils" : "off" }
예제 1. 컴포넌트가 렌더링 확인 1 2 3 4 export function ToggleButton ({ onText, offText, on } ) { return <div > {on ? onText : offText}</div > ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import { render, screen } from "@testing-library/react" ;import { ToggleButton } from "./ToggleButton" ;describe.only ("ToggleButton Test Start!" , () => { test ("컴포넌트가 정상적으로 렌더링 되었습니다." , () => { render (<ToggleButton onText ="1" offText ="0" /> ); const offTextElement = screen.getByText ("0" ); const onTextElement = screen.queryByText ("1" ); expect (offTextElement).toBeInTheDocument (); expect (onTextElement).not .toBeInTheDocument (); }); });
getByText()
: 가상으로 그려진 문서에 존재하는 것만 가져올 수 있다. 만약 존재 하지 않는 다면 오류를 발생시킨다.
queryByText()
: 존재하지 않으면 오류를 발생시키지 않고 null 값으로 가져온다.
2. 활성화 상태 여부에 따라 텍스트 표시 1 2 3 4 export function ToggleButton ({ onText, offText, on } ) { return <button type ="button" > {on ? onText : offText}</button > ; }
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 describe ("ToggleButton 컴포넌트" , () => { test ("활성 상태 여부에 따라 활성(ON)/비활성(OFF) 텍스트가 표시됩니다." , () => { let onText = "ON" ; let offText = "OFF" ; render (<ToggleButton onText ={onText} offText ={offText} /> ); let elements = screen.queryAllByRole ("button" ); let firstElement = elements[0 ]; expect (firstElement).toHaveTextContent (offText); screen.debug (); cleanup (); render (<ToggleButton onText ={onText} offText ={offText} on /> ); elements = screen.queryAllByRole ("button" ); firstElement = elements[0 ]; screen.debug (); expect (firstElement).toHaveTextContent (onText); }); });
만약 on 일때의 text와 off일 때의 text를 찾고 싶다면 queryAllText()
를 사용해준다,
cleanup()
을 해줘야지만 firstElement를 확인할 때, 앞에 그려진 것을 지우고 새로 그려진 것을 비교해줄 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 export function ToggleButton ({ onText, offText, on, onToggle } ) { return ( <button type ="button" className ={ `ToggleButton ${on ? "ToggleButton--on " : ""}`.trim ()} onClick ={onToggle} > {on ? onText : offText} </button > ); }
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 31 describe ("ToggleButton 컴포넌트" , () => { test ("`onToggle` 속성(prop)에 연결된 함수가 정상적으로 실행됩니다." , () => { let expected = "triggering toggle event" ; let received = "" ; render ( <ToggleButton onToggle ={() => { received = expected; }} /> ); expect (received).not .toBe (expected); const element = screen.queryByRole ("button" ); fireEvent.click (element); expect (received).toBe (expected); }); test (`활성 상태의 컴포넌트는 'ToggleButton--on' 클래스 이름을 포함한다.` , () => { let expected = "ToggleButton--on" ; render (<ToggleButton on /> ); const element = screen.getByRole ("button" ); expect (element).toHaveClass (expected); }); });
fireEvent()
: 이벤트를 발생시켜주는 메서드이다.
queryByRole()
: 해당 요소의 역할을 확인하는데 사용된다.
ex) button 태그에 type을 “button”으로 명시적으로 작성하였는지…
🏓 소감 오늘 수업에서 상태를 가지지 않는 컴포넌트의 다양한 테스트 방법에 대해 실습을 진행하였다. 리액트를 TDD 방식으로 개발을 진행하게 된다면 앞서 말한 애플리케이션의 신뢰도 향상할 수 있고 테스트 문서를 생성하여 유지보수를 용이하게 할 수 있다는 생각이 들었다.
아직 jest에 익숙하지 않아 낯설고 어렵지만, 우테코에서도 jest를 사용하고 있고 앞으로 자주 사용해보면서 테스트 주도 개발에 대해 몸을 익히도록 해야겠다.
댓글 공유