스무디 한 잔 마시며 끝내는 리액트 + TDD (4)

y_cat·2022년 8월 28일
0

Jest의 한계

Jest는 js 테스트 프레임워크이다. React도 js이기는 하지만, JSX를 사용하고 있으므로 일반적인 js는 아니며, HTML의 DOM을 다루기 때문에 단순한 js의 테스트로 정확한 오류를 잡아내기는 어렵다.
React뿐만 아니라 Angular, Vue도 js에서 DOM을 직접 다루기 때문에 일반적인 js 테스트 프레임워크로는 모든 테스트를 수행하기 어렵다.



@testing-library

Jest의 한계를 해겨록자 만들어진 DOM 테스트 라이브러리로 사용자 중심 방식으로 UI 컴포넌트를 테스트하는 데 도움을 주는 라이브러리이다.

공식 홈페이지 : https://testing-library.com

github : https://github.com/testing-library/react-testing-library

React, Angular, Vue, Sevelte 등 UI 컴포넌트를 다루는 최신 라이브러리를 각각 지원하고 있다. React 전용의 @testing-library는 react-testing-library이다.



react-testing-library 장점

  • React 컴포넌트를 테스트하기 위한 매우 가벼운 솔루션으로 유지 보수가 가능한 React 컴포넌트용 테스트 코드 작성 가능

  • 테스트 코드에 컴포넌트 세부 구현 사항을 포함하지 않아 세부 구현 부분을 리팩토링하여도 테스트 코드를 수정을 필요가 없음

  • 오랜 기간 유지 가능한 테스트 코드로 자주 수정하지 않아도 되므로 개발 생산성을 향상시켜줌

  • react-dom 위에서 동작하여 실제 DOM 노드에서 작동하므로 더 신뢰할 수 있는 테스트를 할 수 있음

  • 사용자 중심의 테스트 유틸리티 제공 -> react-testing-library의 DOM 찾는 기능이 실제 사용자가 DOM을 사용하는 방식과 유사한 형태로 제공

※ react-testing-library를 사용하기 위해서는 다른 테스트 프레임워크와 함께 사용해야 한다.
공식적으로 Jest와 함께 사용하는 것을 추천



사용 방법

react-testing-library는 Jest와 마찬가지로 create-react-app으로 생성한 React 프로젝트에 기본적으로 같이 설치된다.

reaact-testing-library-test 이름의 React 프로젝트를 생성한다.

npx create-react-app react-testing-library-test


만약 다른 방법으로 react 프로젝트를 생성했을 경우, 다음 명령어를 실행하여 react-testing-library를 설치한다.

npm install --save-dev @testing-library/react



App.test.js 파일을 보면 @testing-library/react에서 renderscreen 메서드를 불러와 테스트에서 사용되고 있음을 알 수 있다.

  • render : 인메모리 DOM에 React 요소를 렌더링하여 container 반환

  • screen : 인메모리 DOM에서 렌더링된 요소를 query하여 text content, attribute 등에 대한 assertion을 만드는 메서드를 제공

render를 통해 App이라는 컴포넌트를 렌더링하고, screen.getByText를 통해 화면에서 'learn react'라는 글자를 가지고 있는 DOM 요소를 찾고 찾은 요소를 Jest의 expect().toBeInTheDocument()를 사용하여 DOM에 표시되어 있는 지를 확인한다.


그리고 Jest 테스트를 실행해본다.

npm run test

만약 다음과 같은 내용의 에러가 나온다면 node 16버전 이상으로 업데이트 시켜야 한다. jest-watch가 Node 16버전 이상으로 요구되기 때문이다.

Error: Failed to initialize watch plugin "node_modules/jest-watch-typeahead/filename.js"

참고 : https://github.com/facebook/create-react-app/issues/11792



테스트 코드 추가

우선 이미지와 설명문을 잘 표시하는지 확인하기 전에 테스트의 명세를 다음과 같이 수정한다.


그리고 이미지가 잘 표시되는지 확인하기 위해 테스트 코드를 추가한다.

container는 React 컴포넌트에서 화면에 표시되는 부분을 담고 있는 오브젝트이다.
이 container를 사용하여 getElementsByClassName 함수로 화면에 표시되고 있는 "<img />" 태그를 클래스 명으로 찾아서 가져 오며 이 요소가 한 개 존재하는 지를 toHaveLength 함수로 확인했다.
또한 실제로 원하는 이미지를 표시하고 있는 지 toHaveAttribute 함수를 사용하여 "<img />" 태그의 src를 가져와 비교하였다.

다시 npm run test를 입력하여 테스트를 실행해본다.


추가로 화면에 설명문("<p />")이 잘 표시되는지 확인해보기 위해 테스트 코드를 추가한다.

container 오브젝트에서 getElementsByTagName 함수를 사용하여 <p> 태그를 찾고 해당 태그가 한 개 존재하고 있음을 toHaveLength 함수를 통해 테스트한다.
또한 해당 p 태그가 원하는 문자열로 잘 표시하고 있는지 toHaveTextContent 함수를 사용하여 테스트한다.


마지막으로 화면에 표시되는 내용이 변경되었는지 알기 위해 스냅샷 테스트를 추가한다.

src/__snapshots__/App.test.js.snap 파일이 생성되어 App 컴포넌트가 화면에 렌더링될 때 표시되는 HTML 내용이 저장된 것을 확인할 수 있다.
스냅샷은 화면에 표시되는 컴포넌트가 변경되었는지 감지하기 위한 테스트로 많이 사용된다고 한다.

스냅샷 테스트가 제대로 동작하는지 확인하기 위해 App.js 파일을 열어 다음과 같이 수정한다.

스냅샷 테스트는 개발자가 React 컴포넌트를 수정했을 때 수정한 내용이 의도치 않게 화면 표시를 변경하는 실수를 알 수 있게 해준다.

만약 컴포넌트를 수정하여 화면 표시가 변경된 것이 의도된 수정이었다면 스냅샷 테스트로 저장된 파일을 업데이트 해주어야 한다.

테스트가 실패했던 터미널에서 'u'키를 누르면 스냅샷 파일이 새로 업데이트되어 다시 이 기준으로 변경을 감지하고 에러를 표시하게 된다.



참고

profile
토이 프로젝트와 기술들 정리하는 블로그

0개의 댓글