웹 통합 테스트

프로바이더

  • 프로바이더를 사용하는 전역 UI를 대상으로 실시하는 테스트의 중점은 다음과 같다.

    • Provider의 상태에 따라 렌더링 여부가 변경됨

    • Provider의 갱신 함수로 상태를 갱신 가능

  • Context를 테스트하는 두 가지 방법

1. 테스트용 컴포넌트를 만들어 인터렉션 실행하기

  • useToastAction 이라는 커스텀 훅을 사용하면 최하위 컴포넌트에서도 <Toast> 렌더링 가능

  • 이를 테스트하고자 테스트용으로만 사용할 컴포넌트를 만들어 실제와 비슷한 상황을 재현해보자.

  • showToast 를 실행할 수만 있으면 되기 때문에 버튼을 클릭하면 showToast가 실행되도록 구현 ㄱ

// 테스트용 컴포넌트
const TestComponent = ({ message }: { message: string }) => {
  const { showToast } = useToastAction();
  return <button onClick={() => showToast(message)}>show</button>
}
  • 테스트 render 함수로 최상위 컴포넌트인 <TestProvider> 와 하위 컴포넌트인 <TestComponent> 를 렌더링 한다.

2. 초깃값을 주입해서 렌더링된 내용 확인하기

  • <TestProvider>PropsdefaultState 라는 초깃값을 설정할 수 있도록 구현됨

  • 단순히 렌더링 여부를 확인하고 싶은거면 defaultState 에 초깃값을 주입해 검증하면 됨

Next.js 라우터 렌더링 통합 테스트

라우터 (페이지 이동과 URL을 관리하는 기능)와 관련된 UI 컴포넌트의 통합 테스트

  • Next.js에서 라우터 부분을 테스트하려면 목 객체를 사용해야 한다.

  • next-router-mock : 제스트에서 Next.js 라우터를 테스트할 수 있도록 목 객체를 제공하는 라이브러리

    • <Link> 컴포넌트에서 발생한 라우터 변화

    • useRouter를 활용한 URL 참조 혹은 변경에 대한 통합 테스트를 jsdom에서 실행 가능

test.each 활용

  • 동일한 테스트를 매개변수만 변경해 반복하고 싶다면 test.each 사용해보자.

입력 통합 테스트

인터렉션 테스트

  • 인터렉션 함수를 별도로 만들어 테스트 코드에서 UI 컴포넌트의 입력을 재현하는 코드를 직관적으로 바꿔보자

검증 범위를 좁히면 UI 컴포넌트의 책임과 이에 따른 테스트 코드가 더욱 명확해진다.

React Hook Form 테스트

  • 폼은 전송하기 전에 입력된 내용을 참조하기 때문에 폼을 구현할 떄 먼저 '어디에서 입력 내용을 참조할 것인지'를 정해야 한다.

    • 제어 컴포넌트: useState 를 사용해 컴포넌트 단위로 상태를 관리하는 컴포넌트

      • 제어 컴포넌트로 구현된 폼은 관리 중인 상태를 필요한 타이밍에 웹 API로 보낸다.

    • 비제어 컴포넌트: 폼을 전송할 떄 <input> 등의 입력 요소에 브라우저 고유 기능을 사용해 값을 참조하도록 구현함

      • 전송시 직접 값을 참조하기 때문에 useState 상태를 관리하지 않아도 되며, ref 로 DOM의 값을 참조

      • value, onChange 를 따로 지정하지 않는다.

      • 제어 컴포넌트에서 useState로 지정한 초깃값은 defaultValue 로 대체

  • React Hook Form은 비제어 컴포넌트로 고성능 폼을 쉽게 작성할 수 있도록 도와주는 라이브러리

  • 입력 요소를 참조하는 ref, 이벤트 핸들러를 자동으로 생성하고 설정해준다.

  • register 는 전송 시 참조할 입력 내용으로 '등록한다'는 의미

  • register함수를 사용하는것만으로 참조와 전송 준비가 완료됨

폼 유효성 검사 테스트

  • 입력 내용에 따라 어떤 유효성 검사가 실시되는지에 중점을 두고 테스트

  • React Hook Form에는 하위 패키지로 resolver 가 있다.

    • 여기에 입력 내용을 검증할 유효성 검사 스키마 객체를 할당 가능

React Hook Form의 handleSubmit 함수의 인수는 함수를 직접 인라인으로 작성하지 않고 Props 에서 취득한 이벤트 핸들러를 지정 할 수도 있다.

  • 해당 컴포넌트의 책임

    • 입력폼 제공

    • 입력 내용 유효성 검사

    • 오류가 있으면 오류 표시

    • 유효 내용이 전송되면 onValid 실행

    • 유효하지 않은 내용이 전송되면 onInvalid 실행

인터렉션 테스트

  • 인터렉션 테스트를 위해 설정 함수에 인터랙션 함수를 추가한다. (개별 인터렉션들을 반환)

화면 이동 테스트

  • 화면 이동은 웹 API 호출이 정상적으로 종료된 후에 발생한다.

  • waitFor 함수로 mockRouterpathname 이 특정 페이지와 일치하는지 검증

이미지 업로드 통합 테스트

파일 업로드 기능은 E2E 테스트에서도 검증 가능하고 통합 테스트에서도 검증 가능하다.

  • 컴퓨터에 저장된 이미지를 선택하여 업로드 시도

  • 이미지 업로드에 성공하면 프로필 이미지로 적용

  • 이미지 업로드에 실패하면 실패했음을 알림

jest로 재현할 수 없는 처리들은 mock 객체를 이용하자.

  • 컴퓨터의 저장된 이미지를 데이터화

  • Next.js에 구현된 이미지 업로드 API

이미지를 선택하는 mock 함수

  • 테스트 환경인 jsdom은 브라우저 API 제공하지 않으므로 이미지 선택(Browser API)를 사용할 수 없음

    • 더미 이미지 파일 작성하기

    • user.upload를 호출해 이미지 선택 인터렉션 재현하기

이미지 업로드 API를 호출하는 mock 함수

  • 이미지 업로드 API를 호출하게되면 Next.js의 API Routes에 요청이 발생하고 AWS S3에 이미지를 업로드 하는 처리가 실행됨

    • 이와 같은 처리까지 UI 컴포넌트 테스트에서 실행하면 본 목적에서 벗어남

    • 그래서 목 함수를 설정해 정해진 응답이 오도록 설정

Last updated