Frontend/React

프론트엔드 테스트 - (1) 프롤로그, Jest 사용 방법

rachel_13 2024. 3. 20. 11:02

프론트엔드에서의 테스트란 (with React)

1. 테스트 목적

💡프로그래밍에서의 테스트란
프로그램을 실행해서 오류, 버그를 검출하고 어플리케이션이 정상적으로 작동하는지 검증하는 과정이다.

 

그렇다면, 왜 테스트를 하는걸까?

 

테스트를 하는 이유에 대해서 간략히 정리해보자면, 다음과 같다.

  • 어플리케이션을 안정적으로 만들기 위해, 버그를 빨리 찾아내서 고치기 위해
  • 디버깅 시간 단축 - 자동화 된 유닛테스트로 특정 버그를 빨리 캐치할 수 있다.
  • 신규 기능 추가시 설계 시간 단축
  • 신규 기능 추가시 발생하는 변경 사항들로 인한 결함을 찾아낼 수 있다.
  • 기존 기능을 리팩토링시 테스트를 실행하여 기능 상 결함이 없음을 보장할 수 있다.
  • 코드에 확신이 생긴다. 컴포넌트가 제대로 작동한다는 것을 테스트 케이스를 통해 보장받을 수 있다.

 

2. 테스트 종류

테스트 피라미드

1) Unit Test (단위 테스트)

어플리케이션 내에서 작은 단위의 code sample을 테스트 하는 것을 의미한다.

React 에서는 Component 하나를 테스트하거나 하나의 어떤 역할을 하는 함수를 테스트 할 수 있을 것이다.

단위 테스트는 가장 짧은 시간이 소요되며, 비용이 가장 적게 든다.

 

2) Integration Test (통합 테스트)

통합 테스트는 여러 개의 Unit Test가 모인 것과 같다. test suite에 가까우며, 여러 코드 블록을 동시에 테스트한다.

예를 들어, 단위 테스트일 경우, 이미지가 로드되는지 여부만 테스트했다면, 통합 테스트에서는 제목이 로드되는지, 이미지가 로드되는지, 올바른 데이터가 표시되는지 등 사용자 흐름을 테스트하는데 유용하다.

통합 테스트는 전체 플로우를 테스트 하지는 않기 때문에 E2E보다는 상대적으로 적은 비용이 든다.

 

3) E2E 테스트 (UI 테스트)

- End To End 또는 UI 테스트라고 불린다.

UI 테스트는 실제 브라우저와 데이터베이스가 로드된 앱 전체, 즉 시스템 뿐만 아니라 소프트웨어 자체를 테스트 하는 것을 의미한다.

어플리케이션이 전체적으로 잘 동작하는지 확인할 수 있는 방법이다.
어플리케이션의 전체 플로우를 테스트하므로, 느리고 작성하기 까다로우며 종종 제대로 동작하지 않는다.
때문에, 개발자들의 발목을 잡을 수도 있다.

개인적으로는 테스트는 자동화를 했을 때 가장 큰 의미가 있다고 생각하는데, E2E 테스트는 자동화하기가 매우 까다롭다.

 

3. 프론트엔드에서의 테스트란?

위의 피라미드 구조를 프론트엔드에서 적용해본다고 가정하자.

서비스의 특성상 사용자의 요구사항에 따라 기획이나 디자인이 자주 변경되고는 한다.


상대적으로 프론트엔드는 UI가 자주 바뀌다보니 위와 같은 피라미드 구조로 테스트를 하게 되면

테스트 코드를 업데이트 하는데 많은 시간을 할애해야 하는 상황이 발생할 수도 있게 된다.

 

그래서, RTL의 창시자 Kent C. Dodds는 테스팅 트로피 방법론을 제시한다.

 

 

 

테스팅 트로피 (by Kent C. Dodds)

 

통합 테스트에 집중해야 한다는 것을 강조한다.

 

통합 테스트의 경우 유닛 테스트와 달리, 한 페이지 또는 기능 전체에 대한 테스트를 수행하다 보니 커버할 수 있는 범위가 넓다.
또한 유닛 테스트는 리팩토링 후 종종 수정이 발생하는 반면 통합 테스트의 경우 변경사항이 적다.

 

마지막으로 통합 테스트는 사용자의 흐름을 중심으로 작성되었기 때문에, 우리가 예상한대로 동작하는지를 검증할 수 있으며, 테스트 결과를 신뢰할 수 있게 된다.

 

4. 리액트에서의 테스트

1) Jest란?

  • Facebook에서 개발한 오픈 소스 테스트 프레임워크
  • JavaScript 및 TypeScript를 지원
  • React, Vue.js, Angular 등 다양한 프레임워크와 함께 사용 가능

 

1-1. Jest 파일 구조

tests 폴더에 저장하도록 권장한다.

  • 기본적으로 Jest는 자동으로 test 파일을 찾아서 test case를 실행하는데, tests 폴더가 기본 위치이다.
  • 파일명: 테스트 대상 코드 파일 이름과 일치하도록 명명
  • 확장자: .test.js 또는 .test.tsx와 같이 .test를 포함합니다.

예시:

__tests__/
├── App.test.js
├── MyComponent.test.js
└── MyService.test.tsx

 

1-2. Jest 사용법

  1. 테스트 코드 작성
describe("MyComponent", () => {
  it("should render correctly", () => {
    const { getByText } = render(<MyComponent />);
    expect(getByText("Hello, Jest!")).toBeInTheDocument();
  });
});
  • describe: 테스트 대상을 정의한다. 블록 단위로 정의하여 그룹화 할 수 있다.
  • it(test): 테스트 케이스를 정의한다. 개별 테스트 항목을 정의하고 직접적으로 수행한다.
  • render: 테스트 대상 컴포넌트를 렌더링한다.
  • expect: 값을 테스트하며, 주로 match함수와 함께 사용된다.
  • matcher: 값을 테스트를 할 수 있는 여러 가지 함수들을 의미한다.

 

[참고] 자주 사용되는 matcher들

Matchers 정의
.toBe(value) .toBe를 사용하여 원시 값을 비교하거나 객체 인스턴스의 참조 id를 엄격하게 비교
.toEqual(value) 객체 or 배열같은 복합 데이터 구조의 모든 프로퍼티를 재귀적으로 비교해서
값이 동일한지 비교 (깊은 비교)
.not(value) matcher의 반대조건 수행 예) .not.toBe(value) : 값이 주어진 값과 다름을 확인
.toBeFalsy(value) 값이 거짓(falsy)값인지 확인
.toBeTruthy(value) 값이 참(truthy)값인지 확인
.toBeGreaterThan(number) 값 > 숫자(number)인지 확인
.toBeGreaterThnaOrEqual(number) 값 >= 숫자(number)인지 확인
.toBeLessThan(number) 값 < 숫자(number)인지 확인
.toBeLessThanOrEqual(number) 값 <= 숫자(number)인지 확인
.toBeInstanceOf(Class) 주어진 객체가 특정 클래스의 인스턴스인지 확인
.toBeDefined() 값이 undefined가 아닌지 확인
.toBeUndefined() 값이 undefined인지 확인
.toBeNull() 값이 null인지 확인
.toBeNaN() 값이 NaN인지 확인
.toContain(item) 배열이 특정 항목(item)을 포함하는지 확인
.toContainEqual(item) 배열이 특정 객체나 값과 일치하는(동등한) 항목을 포함하는지 확인
.toHaveProperty(keyPath, value?) 객체가 키 값에 해당하는 프로퍼티를 가지고 있는지,
(optional)그 값이 주어진 값과 동일한 지 확인
.toHaveLength(number) 객체가 .length 프로퍼티를 가지고 있고, 그 길이가 주어진 숫자와 동일한 지 확인
.toMatch(regexp | string) 문자열이 정규표현식과 일치하거나 문자열이 주어진 문자열을 포함하는지 확인
.toMatchObject(object) 객체가 주어진 객체와 일치하는지
.toThrow(error?) 함수가 호출될 때 오류를 던지는지 확인,
(optional)특정 오류 또는 오류 메세지가 던져지는지 확인

 

 

      예시:
test("two plus three is five", () => {
  expect(2 + 3).toBe(5);
});

test("two plus three is not four", () => {
  expect(2 + 2).not.toBe(4);
});

 

  1. 테스트 실행
npx jest

 

  1. 테스트 결과 확인

Jest는 테스트 결과를 콘솔에 출력한다.
테스트가 성공하면 녹색 체크 표시, 실패하면 빨간색 엑스 표시가 나타납니다.

테스트 실패시
테스트 성공시

 

  1. 테스트 디버깅
  • --inspect 옵션: 테스트 실행 시 Chrome DevTools를 자동으로 열 수 있음.
  • debugger 키워드: 테스트 코드 실행 중 특정 지점에서 중단.

 

1-3. Jest 기능

  • 단위 테스트: 컴포넌트, 함수, 클래스 등의 단위 테스트를 지원
  • 스냅샷 테스트: UI 요소의 스냅샷을 생성하고 비교하여 UI 변경을 확인
  • 모듈 시스템: 테스트 파일을 모듈로 구성하여 관리
  • 커버리지 보고: 테스트 코드 커버리지 보고서 생성

 

 

 

 

 

* 참고

따라하며 배우는 리액트 테스트

https://youtu.be/pkYUcKWOqPs?si=2-AMW5e2_un9OCca

https://medium.com/bitsrc/how-to-do-test-driven-development-in-react-using-react-testing-library-jest-and-cypress-baf0eade6e3b

https://kentcdodds.com/blog/static-vs-unit-vs-integration-vs-e2e-tests

https://delivan.dev/react/modern-react-testing-part-1/

 

 

 

 

 

 

 

프론트엔드 테스트 - (2) React Testing Library

React Testing Library 1. 개요 - Facebook에서 만든 오픈소스 테스팅 프레임워크 - Javascript와 Typescript 를 지원한다. - React, Vue, Angular 등의 프레임워크에서 지원한다. - 참고) CRA 설치시 기본으로 RTL이 세팅

rachelslab.tistory.com