Jest로 React 애플리케이션을 테스트하기 위한 실용적인 가이드
게시 됨: 2022-03-10이 기사에서는 React 구성 요소를 테스트하도록 설계된 인기 있는 라이브러리 Enzyme과 함께 Jest라는 React 테스트 도구를 소개하겠습니다. 테스트 실행, React 구성 요소 테스트, 스냅샷 테스트 및 조롱을 포함한 Jest 테스트 기술을 소개합니다. 테스트가 처음이고 시작하는 방법이 궁금하다면 테스트 소개부터 시작하기 때문에 이 튜토리얼이 도움이 될 것입니다. 결국 Jest와 Enzyme을 사용하여 React 애플리케이션을 테스트하고 실행하게 될 것입니다. 이 튜토리얼을 따르려면 React에 익숙해야 합니다.
테스트에 대한 간략한 소개
테스트는 코드가 실행되는 방식을 한 줄씩 검토하는 것입니다. 응용 프로그램에 대한 테스트 모음은 응용 프로그램이 오류 없이 성공적으로 실행되고 있는지 확인하기 위한 다양한 코드로 구성됩니다. 테스트는 코드를 업데이트할 때도 유용합니다. 코드를 업데이트한 후 테스트를 실행하여 업데이트로 인해 애플리케이션에 이미 있는 기능이 중단되지 않는지 확인할 수 있습니다.
왜 테스트?
우리가 어떤 일을 하기 전에 그 일을 하는 이유를 이해하는 것이 좋습니다. 그렇다면 왜 테스트하고 그 목적은 무엇입니까?
- 테스트의 첫 번째 목적은 회귀를 방지하는 것입니다. 회귀는 이전에 수정된 버그가 다시 나타나는 것입니다. 특정 이벤트가 발생한 후 기능이 의도한 대로 작동하지 않도록 합니다.
- 테스트는 복잡한 구성 요소 및 모듈식 응용 프로그램의 기능을 보장합니다.
- 테스트는 소프트웨어 응용 프로그램 또는 제품의 효과적인 성능을 위해 필요합니다.
테스트를 통해 앱이 더 강력해지고 오류가 발생하기 쉽습니다. 코드가 원하는 작업을 수행하고 앱이 사용자를 위해 의도한 대로 작동하는지 확인하는 방법입니다.
테스트의 유형과 수행하는 작업에 대해 알아보겠습니다.
단위 테스트
이 유형의 테스트에서는 소프트웨어의 개별 단위 또는 구성 요소가 테스트됩니다. 단위는 개별 기능, 메서드, 프로시저, 모듈 또는 개체일 수 있습니다. 단위 테스트는 소프트웨어 코드의 각 단위가 예상대로 작동하는지 검증하기 위해 코드 섹션을 분리하고 정확성을 검증합니다.
단위 테스트에서는 개별 절차나 기능이 제대로 작동하는지 테스트하고 모든 구성 요소를 개별적으로 테스트합니다. 예를 들어, 함수를 테스트하거나 프로그램의 명령문이나 루프가 제대로 작동하는지 여부는 단위 테스트 범위에 속합니다.
구성 요소 테스트
구성 요소 테스트는 응용 프로그램의 개별 부분의 기능을 확인합니다. 테스트는 다른 구성 요소와 분리되어 각 구성 요소에 대해 수행됩니다. 일반적으로 React 애플리케이션은 여러 구성 요소로 구성되므로 구성 요소 테스트는 이러한 구성 요소를 개별적으로 테스트합니다.
예를 들어, 많은 구성 요소가 있는 서로 다른 웹 페이지가 있는 웹 사이트를 고려하십시오. 모든 구성 요소에는 자체 하위 구성 요소가 있습니다. 다른 구성 요소와의 통합을 고려하지 않고 각 모듈을 테스트하는 것을 구성 요소 테스트라고 합니다.
React에서 이와 같은 테스트를 하려면 더 정교한 도구가 필요합니다. 따라서 Jest와 Enzyme과 같은 더 정교한 도구가 필요합니다. 이에 대해서는 나중에 간단히 설명하겠습니다.
스냅샷 테스트
스냅샷 테스트는 웹 애플리케이션의 사용자 인터페이스(UI)가 예기치 않게 변경되지 않는지 확인합니다. 그것은 한 순간에 구성 요소의 코드를 캡처하여 한 상태의 구성 요소를 취할 수 있는 다른 가능한 상태와 비교할 수 있습니다.
스냅샷 테스트에 대해서는 이후 섹션에서 배울 것입니다.
테스트의 장점과 단점
테스트는 훌륭하고 수행해야 하지만 장점과 단점이 있습니다.
장점
- 예상치 못한 회귀를 방지합니다.
- 개발자는 과거에 대해 걱정하지 않고 현재 작업에 집중할 수 있습니다.
- 빌드하기에는 너무 복잡할 애플리케이션을 모듈식으로 구성할 수 있습니다.
- 수동 검증의 필요성이 줄어듭니다.
단점
- 더 많은 코드를 작성하고 디버그 및 유지 관리해야 합니다.
- 중요하지 않은 테스트 실패로 인해 앱이 지속적인 통합 측면에서 거부될 수 있습니다.
Jest 소개
Jest는 단순성에 중점을 둔 유쾌한 JavaScript 테스트 프레임워크입니다. npm 또는 Yarn으로 설치할 수 있습니다. Jest는 테스트 러너로 알려진 더 넓은 범주의 유틸리티에 적합합니다. React 애플리케이션에서 훌륭하게 작동하지만 React 애플리케이션 외부에서도 훌륭하게 작동합니다.
Enzyme은 React 애플리케이션을 테스트하는 데 사용되는 라이브러리입니다. 구성 요소를 테스트하도록 설계되었으며 UI가 올바르게 작동하는지 확인하는 작업을 시뮬레이션하는 어설션을 작성할 수 있습니다.
Jest와 Enzyme은 서로를 잘 보완하므로 이 기사에서는 둘 다 사용할 것입니다.
Jest로 테스트를 실행하는 과정
이 섹션에서는 Jest를 설치하고 테스트를 작성합니다. React가 처음이라면 Create React App을 사용하는 것이 좋습니다. Create React App은 사용할 준비가 되어 있고 Jest와 함께 제공되기 때문입니다.
npm init react-app my-app
React react-test-renderer
를 사용하여 Enzyme **** 및 enzyme-adapter-react-16
을 설치해야 합니다(숫자는 사용 중인 React 버전을 기반으로 해야 함).
npm install --save-dev enzyme enzyme-adapter-react-16 react-test-renderer
이제 Jest와 Enzyme으로 프로젝트를 생성했으므로 프로젝트의 src
폴더에 setupTest.js
파일을 생성해야 합니다. 파일은 다음과 같아야 합니다.
import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; configure({ adapter: new Adapter() });
이것은 Enzyme을 가져오고 테스트를 실행하도록 어댑터를 설정합니다.
계속하기 전에 몇 가지 기본 사항을 알아보겠습니다. 몇 가지 핵심 사항은 이 기사에서 많이 사용되며 이를 이해해야 합니다.
-
it
또는test
이 메서드에 함수를 전달하면 테스트 실행자가 해당 기능을 테스트 블록으로 실행할 것입니다. -
describe
이 선택적 메서드는 임의의 수의it
또는test
문을 그룹화하기 위한 것입니다. -
expect
테스트를 통과해야 하는 조건입니다. 수신된 매개변수를 matcher와 비교합니다. 또한 다양한 항목의 유효성을 검사할 수 있는 여러 매처에 액세스할 수 있습니다. 문서에서 이에 대한 자세한 내용을 읽을 수 있습니다. -
mount
이 메서드는 테스트를 실행 중인 부모 구성 요소의 자식 구성 요소를 포함하여 전체 DOM을 렌더링합니다. -
shallow
이것은 우리가 테스트하는 개별 구성 요소만 렌더링합니다. 자식 구성 요소를 렌더링하지 않습니다. 이를 통해 구성 요소를 개별적으로 테스트할 수 있습니다.
테스트 파일 생성
Jest는 테스트 파일이 무엇이고 무엇이 아닌지 어떻게 압니까? 첫 번째 규칙은 디렉토리에서 __test__
라는 이름을 가진 모든 파일이 테스트로 간주된다는 것입니다. JavaScript 파일을 이러한 폴더 중 하나에 넣으면 Jest는 좋든 나쁘든 Jest를 호출할 때 해당 파일을 실행하려고 합니다. 두 번째 규칙은 Jest가 .spec.js
또는 .test.js
접미사가 있는 모든 파일을 인식한다는 것입니다. 전체 저장소의 모든 폴더와 모든 파일의 이름을 검색합니다.
이 튜토리얼을 위해 만든 React 미니 애플리케이션에 대한 첫 번째 테스트를 만들어 보겠습니다. GitHub에서 복제할 수 있습니다. npm install
을 실행하여 모든 패키지를 설치한 다음 npm start
를 실행하여 앱을 시작합니다. 자세한 내용은 README.md
파일을 확인하십시오.
App.test.js
를 열어 첫 번째 테스트를 작성해 보겠습니다. 먼저 앱 구성 요소가 올바르게 렌더링되는지와 출력을 지정했는지 확인합니다.
it("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const welcome = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(welcome)).toEqual(true); });
위의 테스트에서 첫 번째 테스트는 shallow
으로 앱 구성 요소가 충돌 없이 올바르게 렌더링되는지 확인합니다. shallow
방법은 자식 구성 요소 없이 단일 구성 요소만 렌더링한다는 것을 기억하십시오.
두 번째 테스트는 toEqual
의 Jest matcher를 사용하여 앱 구성 요소에서 "Display Active User Account"의 h1
태그 출력을 지정했는지 확인합니다.
이제 테스트를 실행합니다.
npm run test /* OR */ npm test
터미널의 출력은 다음과 같아야 합니다.
PASS src/App.test.js √ renders without crashing (34ms) √ renders Account header (13ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 11.239s, estimated 16s Ran all test suites related to changed files. Watch Usage: Press w to show more.
보시다시피 테스트가 통과했습니다. Jest가 실행되었을 때 두 개의 성공적인 테스트와 함께 App.test.js
라는 하나의 테스트 스위트가 있음을 보여줍니다. 스냅샷 테스트에 대해서는 나중에 이야기하고 실패한 테스트의 예도 보게 될 것입니다.
테스트 건너뛰기 또는 격리
테스트를 건너뛰거나 격리한다는 것은 Jest가 실행될 때 표시된 특정 테스트가 실행되지 않는다는 것을 의미합니다.
it.skip("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const header = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(header)).toEqual(true); });
첫 번째 테스트는 skip
메서드를 사용하여 테스트를 분리했기 때문에 건너뜁니다. 따라서 Jest가 실행될 때 테스트가 실행되거나 변경되지 않습니다. 두 번째 것만 실행됩니다. it.only()
를 사용할 수도 있습니다.

테스트 파일을 변경하고 수동으로 npm test
를 다시 실행해야 하는 것은 약간 답답합니다. Jest에는 파일 변경 사항을 감시하고 그에 따라 테스트를 실행하는 감시 모드라는 멋진 기능이 있습니다. Jest를 watch 모드로 실행하려면 npm test -- --watch
또는 jest --watch
--watch 를 실행할 수 있습니다. 나는 또한 이 튜토리얼의 나머지 부분에 대해 터미널 창에서 Jest를 실행하는 것을 권장합니다.
조롱 기능
모의는 실제 내부 작동 없이 객체 또는 모듈의 확실한 복제본입니다. 약간의 기능이 있을 수 있지만 실제와 비교하면 모의입니다. Jest에 의해 자동으로 생성되거나 수동으로 생성될 수 있습니다.
왜 우리는 조롱해야 합니까? Mocking은 종속성 수, 즉 테스트가 실행될 때 로드되고 구문 분석되어야 하는 관련 파일의 수를 줄입니다. 따라서 모의 객체를 많이 사용하면 테스트가 더 빨리 실행됩니다.
모의 함수는 "스파이"라고도 알려져 있는데, 그 이유는 출력을 테스트하는 것보다 다른 코드에서 직접 호출하는 함수의 동작을 감시할 수 있기 때문입니다.
함수를 모의하는 두 가지 방법이 있습니다. 테스트 코드에서 사용할 모의 함수를 생성하거나 모듈 종속성을 재정의하는 수동 모의를 작성하는 것입니다.
수동 모의 ****는 모의 데이터로 기능을 제거하는 데 사용됩니다. 예를 들어, 웹사이트나 데이터베이스와 같은 원격 리소스에 액세스하는 대신 가짜 데이터를 사용할 수 있는 수동 모의를 만들고 싶을 수 있습니다.
다음 섹션에서 모의 함수를 사용할 것입니다.
React 컴포넌트 테스트하기
이 섹션에서는 React 구성 요소를 테스트하는 방법을 이해하기 위해 지금까지 얻은 모든 지식을 결합합니다. 테스트에는 구성 요소의 출력이 예기치 않게 다른 것으로 변경되지 않았는지 확인하는 작업이 포함됩니다. 올바른 방법으로 구성 요소를 구성하는 것이 성공적인 테스트를 보장하는 가장 효과적인 방법입니다.
우리가 할 수 있는 한 가지는 구성 요소 소품을 테스트하는 것입니다. 특히 한 구성 요소의 소품이 다른 구성 요소로 전달되는지 여부를 테스트하는 것입니다. Jest와 Enzyme API를 사용하면 구성 요소 간에 소품이 전달되는지 여부를 시뮬레이션하는 모의 함수를 만들 수 있습니다.
기본 App
구성 요소에서 Account
구성 요소로 사용자 계정 소품을 전달해야 합니다. 사용자의 활성 계정을 렌더링하려면 사용자 계정 세부 정보를 Account
에 제공해야 합니다. 이것이 바로 조롱이 유용한 곳이므로 가짜 데이터로 구성 요소를 테스트할 수 있습니다.
user
props에 대한 mock을 생성해 보겠습니다.
const user = { name: "Adeneye David", email: "[email protected]", username: "Dave", };
테스트 파일에 수동 모의 함수를 만들고 구성 요소 주위에 래핑했습니다. 대규모 사용자 데이터베이스를 테스트한다고 가정해 보겠습니다. 테스트 파일에서 직접 데이터베이스에 액세스하는 것은 바람직하지 않습니다. 대신 가짜 데이터를 사용하여 구성 요소를 테스트할 수 있는 모의 함수를 만듭니다.
describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });
describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });
위의 두 가지 테스트가 있으며 테스트 중인 구성 요소를 사용하는 describe
레이어를 사용합니다. 테스트에서 통과할 것으로 예상되는 소품과 값을 지정하여 계속 진행할 수 있습니다.
첫 번째 테스트에서는 탑재된 구성 요소에 전달한 props가 위에서 생성한 mock props와 같은지 확인합니다.
두 번째 테스트에서는 마운트된 Account
구성 요소에 사용자 소품을 전달합니다. 그런 다음 Account
구성 요소에 있는 항목에 해당하는 <p>
요소를 찾을 수 있는지 확인합니다. 테스트 스위트를 실행하면 테스트가 성공적으로 실행되는 것을 볼 수 있습니다.
구성 요소의 상태를 테스트할 수도 있습니다. 오류 메시지의 상태가 null인지 확인합시다.
it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });
it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });
이 테스트에서는 toEqual()
매처를 사용하여 구성 요소 오류의 상태가 null인지 확인합니다. 앱에 오류 메시지가 있으면 실행 시 테스트가 실패합니다.
다음 섹션에서는 또 다른 놀라운 기술인 스냅샷 테스트로 React 구성 요소를 테스트하는 방법을 살펴보겠습니다.
스냅샷 테스트
스냅샷 테스트는 테스트와 함께 저장된 참조 스냅샷 파일과 비교하기 위해 특정 시점에 구성 요소의 코드를 캡처합니다. 앱 UI의 변경 사항을 추적하는 데 사용됩니다.
스냅샷의 실제 코드 표현은 JSON 파일이며 이 JSON에는 스냅샷이 만들어졌을 때 구성 요소의 모양에 대한 레코드가 포함되어 있습니다. 테스트 중에 Jest는 이 JSON 파일의 내용을 테스트 중 구성 요소의 출력과 비교합니다. 일치하면 테스트를 통과합니다. 그렇지 않으면 테스트가 실패합니다.
Enzyme 래퍼를 Jest 스냅샷 테스트와 호환되는 형식으로 변환하려면 enzyme-to-json
을 설치해야 합니다.
npm install --save-dev enzyme-to-json
스냅샷 테스트를 생성해 보겠습니다. 처음 실행하면 해당 구성 요소 코드의 스냅샷이 구성되어 src
디렉토리의 새 __snapshots__
폴더에 저장됩니다.
it("renders correctly", () => { const tree = shallow(<App />); expect(toJson(tree)).toMatchSnapshot(); });
위의 테스트가 성공적으로 실행되면 현재 UI 구성 요소가 기존 구성 요소와 비교됩니다.
이제 테스트를 실행해 보겠습니다.
npm run test
테스트 스위트가 실행되면 새 스냅샷이 생성되어 __snapshots__
폴더에 저장됩니다. 이후에 테스트를 실행할 때 Jest는 구성 요소가 스냅샷과 일치하는지 확인합니다.
이전 섹션에서 설명했듯이 Enzyme 패키지의 shallow
메서드는 단일 구성 요소를 렌더링하는 데 사용되며 다른 것은 없습니다. 자식 구성 요소를 렌더링하지 않습니다. 오히려 코드를 분리하고 디버깅할 때 더 나은 정보를 얻을 수 있는 좋은 방법을 제공합니다. mount
라는 또 다른 방법은 테스트를 실행 중인 상위 구성 요소의 하위 구성 요소를 포함하여 전체 DOM을 렌더링하는 데 사용됩니다.
또한 스냅샷을 업데이트할 수 있습니다. 테스트 실패를 위해 구성 요소를 약간 변경하겠습니다. 구성 요소가 더 이상 스냅샷 파일에 있는 것과 일치하지 않기 때문에 이러한 문제가 발생합니다. 이를 위해 컴포넌트의 <h3>
태그를 <h3> Loading...</h3>
에서 <h3>Fetching Users...</h3>
로 변경해 보겠습니다. 테스트가 실행되면 터미널에 다음이 표시됩니다.
FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received
7 | it("올바른 렌더링", () => { 8 | const 래퍼 = 얕은( FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received
활성 사용자 계정 세부 정보 표시
- 로딩 중... + 사용자를 가져오는 중...
); > 9 | 기대(toJson(래퍼)).toMatchSnapshot(); | ^ 10 | }); 11 | 12 | /* it("크래시 없이 렌더링", () => { 개체에서. (src/App.test.js:9:27) › 1개의 스냅샷이 실패했습니다. 스냅샷 요약 › 1개의 테스트 스위트에서 1개의 스냅샷이 실패했습니다. 코드 변경 사항을 검사하거나 'u'를 눌러 업데이트하세요. 테스트 스위트: 1개 실패, 총 1개 테스트: 1개 실패, 총 1개 스냅샷: 1개 실패, 총 1개 시간: 92.274초 변경된 파일과 관련된 모든 테스트 스위트를 실행했습니다. 시청 방법: 더 보려면 w를 누르십시오.
테스트를 통과하려면 테스트를 이전 상태로 변경하거나 스냅샷 파일을 업데이트합니다. 명령줄에서 Jest는 스냅샷을 업데이트하는 방법에 대한 지침을 제공합니다. 먼저 명령줄에서 w
를 눌러 더 많이 표시한 다음 u
를 눌러 스냅샷을 업데이트합니다.
› Press u to update failing snapshots.
스냅샷을 업데이트하기 위해 u
를 누르면 테스트가 통과됩니다.
결론
이 튜토리얼을 통해 즐겁게 작업하셨기를 바랍니다. 우리는 Enzyme 테스팅 라이브러리를 사용하여 Jest 테스팅 기술을 배웠습니다. 또한 테스트 실행, React 구성 요소 테스트, mocking 및 스냅샷 테스트 프로세스에 대해서도 소개했습니다. 질문이 있는 경우 아래의 댓글 섹션에 질문을 남길 수 있습니다. 모든 질문에 기꺼이 답변하고 문제를 해결해 드리겠습니다.
리소스 및 추가 읽을거리
- 농담 문서
- 효소 문서
- "React 구성 요소를 테스트하는 방법: 전체 안내서", Mohammad Iqbal, freeCodeCamp
- "Jest와 효소로 반응 테스트하기", Dominic Fraser, CodeClan