Testing Library와 Jest에 대해 알아보자

지은·2023년 8월 8일
1

Testing Library

CRA를 이용해서 프로젝트를 만들면, package.json에 아래와 같은 라이브러리들이 포함되어 있는 것을 볼 수 있다.

"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",

이 세 개의 라이브러리는 React Testing Library와 관련된 테스트 도구들로, 각각의 역할은 아래와 같다.


@testing-library/jest-dom

  • 이 라이브러리는 Jest 테스트 프레임워크와 함께 사용되며, DOM 요소에 대한 매처(matcher)를 제공한다.
  • 매처는 DOM 요소의 속성(attribute)이나 상태(state)에 따라 테스트를 작성할 수 있도록 도와준다.
    예를 들어, 요소가 활성화되어있는지 여부를 테스트하거나, 특정 텍스트를 포함하고 있는지 확인하는 등의 작업을 할 수 있다.

Testing Library - jest-dom

expect(screen.queryByTestId('not-empty')).not.toBeEmptyDOMElement() 
// queryByTestId 매처를 이용해 testId가 'not-empty'인 DOM 요소를 선택

expect(screen.getByText('Visible Example')).toBeVisible() 
// getByText 매처를 이용해 text가 'Visible Example'인 DOM 요소를 선택

@testing-library/react

  • React Testing Library의 핵심 패키지로, React 컴포넌트 테스트를 위한 함수와 도구를 제공한다.
  • render, screen, fireEvent 등과 같은 함수를 사용해 컴포넌트를 렌더링(render)하고, 화면(screen)에 표시된 요소를 선택하며, 사용자 이벤트를 발생(fireEvent)시키고 테스트하는 등의 작업을 수행할 수 있다.

Testing Library - React Testing Library

import { render, screen, fireEvent } from '@testing-library/react';

test('버튼을 클릭하면 메시지가 변경되어야 함', () => {
  render(<App />); // App 컴포넌트를 렌더링

  const button = screen.getByRole('button'); // 화면에서 role이 button인 요소를 선택
  const message = screen.getByText('기본 메시지'); // 화면에서 text가 '기본 메시지'인 요소를 선택

  fireEvent.click(button); // 버튼에 클릭 이벤트를 발생시킨다.

  expect(message).toHaveTextContent('새로운 메시지'); // message 요소의 textContent가 '새로운 메시지'인지 확인한다.
});

@testing-library/user-event

user-event는 기본 제공되는 fireEvent 메서드보다 브라우저 상호 작용에 대한 고급 시뮬레이션을 제공하는 Testing Library용 컴패니언 라이브러리입니다.

  • 사용자가 실제로 컴포넌트와 상호작용하는 것과 유사한 방식으로 테스트 이벤트를 발생시키는 도구를 제공한다.
  • 일반적인 DOM 이벤트 외에도 키보드 입력, 포커스 이동 등을 시뮬레이션하는 데 사용된다.
  • 이를 통해 테스트 시나리오를 실제 사용자 경험에 가깝게 모방할 수 있다.

Testing Library - user-eventv13

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('인풋 필드에 텍스트 입력', () => {
  render(<InputForm />);

  const input = screen.getByRole('textbox');

  userEvent.type(input, 'Hello, World!');

  expect(input).toHaveValue('Hello, World!');
});

Testing Library를 사용하면 좋은 점

1. 사용자 중심 테스트 → 신뢰성 up

@testing-library 패키지를 사용하면 UI 구성 요소를 사용자 중심 방식으로 테스트할 수 있다.
사용자와 페이지와의 상호작용에 중점을 둔 테스트,
실제 사용자 경험과 유사한 테스트를 통해 애플리케이션의 신뢰성을 높일 수 있다.

2. 내부 구현 분리 → 효율적인 리팩토링

testing-library를 사용하면, 컴포넌트의 내부 구현 사항을 테스트에서 분리할 수 있다.
따라서 나중에 코드 리팩토링 작업을 할 때(기능은 변경되지 않고 내부 구현만 수정하는 경우), 테스트를 다시 작성하고 수정할 필요 없이 기존의 테스트를 여전히 통과하는지 확인할 수 있다.
이는 리팩토링 작업을 훨씬 더 효율적이고 안정적으로 진행할 수 있도록 도와준다.


또한, Testing Library의 공식 문서에서는 아래와 같은 내용도 찾을 수 있다.
Testing Library

이 라이브러리는...

  • 테스트 러너 또는 프레임워크가 아닙니다.
  • 테스트 프레임워크에 특정하지 않습니다.
    DOM Testing Library는 Jest, Mocha + JSDOM 또는 실제 브라우저와 같은 DOM API를 제공하는 모든 환경에서 작동합니다.

Testing Library에서 피해야 할 사항

  • Testing Library는 테스트 중인 컴포넌트의 내부 구현 세부 사항을 테스트하지 않도록 권장합니다.
  • 대신, 웹 페이지가 사용자에 의해 상호 작용하는 방식과 유사한 테스트를 작성하는 것에 중점을 두기를 바랍니다.

다음과 같은 구현 세부 정보는 피해야 합니다 :

  • 컴포넌트의 내부 상태(state)
  • 컴포넌트의 내부 메소드
  • 컴포넌트의 라이프사이클 방식
  • 하위(자식) 컴포넌트

Testing Library가 테스트 러너가 아니라는 건 무슨 뜻일까?

테스트 러너(Test Runner)는 테스트 코드를 실행하고 결과를 보고하는 도구로, 테스트 코드의 실행 환경을 설정하고 각각의 테스트 케이스를 실행하여 결과를 표시한다.

Testing Library는 테스트 러너가 아니라, 테스트 코드 내에서 UI 컴포넌트를 테스트하는 데 도움을 주는 "유틸리티 라이브러리"이다.
따라서 Testing Library는 테스트 코드를 실행하는 환경을 제공하지 않고, 테스트를 실행하지도 않는다. 대신 테스트 코드 내에서 실제 사용자와 유사한 방식으로 UI 컴포넌트를 조작하고 검증하기 위한 도구들을 제공할 뿐이다.

테스팅 라이브러리와 테스트 러너

테스팅 라이브러리와 테스트 러너는 소프트웨어 개발에서 테스트를 관리하고 실행하는 데 사용되는 두 가지 다른 컨셉이다.

🛠 테스팅 라이브러리 (Testing Library)

테스팅 라이브러리는 테스트 코드를 작성하고 테스트할 수 있는 도구를 제공한다.

  • 이러한 라이브러리는 주로 테스트 코드 내에서 예상 결과를 검증하고, 실제 동작을 시뮬레이션하며, 테스트 환경을 구축하고 관리하는 데 사용된다.
  • 테스팅 라이브러리는 코드를 테스트하는 방법, 어떤 기능을 사용하여 검증할지, 어떻게 모의(mock)할지 등을 정의하는 데 도움을 준다.
  • 대표적인 테스팅 라이브러리로는 Jest, React Testing Library, Enzyme 등이 있다.

🖨 테스트 러너 (Test Runner)

테스트 러너는 테스트 코드를 실행하고 결과를 보고하는 역할을 한다.

  • 테스트 코드의 실행 환경을 설정하고, 각 테스트 케이스를 실행하여 그 결과를 표시한다.
  • 테스트 러너는 테스트 스위트를 관리하고, 테스트 결과를 출력하며, 테스트 환경의 초기화와 정리를 담당한다.
  • 대표적인 테스트 러너로는 Jest, Mocha, Jasmine, Karma 등이 있다.

그렇다면 테스트 러너로 무엇을 사용해야 할까?
대표적인 테스트 러너로 Jest가 있다.

Jest

Jest는 JavaScript 테스트 프레임워크로,

  • 테스트를 작성하고 실행하는 데 필요한 다양한 기능과 도구를 제공하여 개발자들이 손쉽게 테스트 코드를 작성하고 실행할 수 있도록 돕는다.
  • 주로 유닛 테스트와 통합 테스트를 위해 사용되며, 리액트를 포함한 다양한 프레임워크와 라이브러리와 함께 사용할 수 있다.

Jest

Jest is a delightful JavaScript Testing Framework with a focus on simplicity.
It works with projects using: Babel, TypeScript, Node, React, Angular, Vue and more!

Jest는 심플함에 초점을 맞춘 사용하기에 즐거운 자바스크립트 테스트 프레임워크입니다.
Babel, TypeScript, Node, React, Angular, Vue 등을 사용한 프로젝트에서 작동합니다!

간편한 구문

Jest는 직관적이고 간결한 테스트 구문을 제공하여 테스트 코드를 더 읽기 쉽게 작성할 수 있게 도와준다.
jest - Expect

Expect

expect 함수는 값을 테스트하고 싶을 때 사용하며, 주로 매처 함수와 함께 사용한다. (예시에서는 toBe 가 매처 함수이다.)

test('the best flavor is chocolate', () => {
  expect(bestIceCreamFlavor()).toBe('chocolate');
  // bestIceCreamFlavor() 함수의 반환값이 'chocolate'과 일치하는지 검사
});

Modifier

not과 같은 modifier를 사용하여 기대 결과를 부정할 수도 있다.

test('the best flavor is not coconut', () => {
  expect(bestIceCreamFlavor()).not.toBe('coconut');
  // bestIceCreamFlavor() 함수의 반환값이 'coconut'이 아닌지 검사
});

Matchers

위에서 사용한 toBe도 있고, toBeTruthy, toEqual, toHaveProperty 등 다양한 매처를 제공한다.

const can1 = {
  flavor: 'grapefruit',
  ounces: 12,
};
const can2 = {
  flavor: 'grapefruit',
  ounces: 12,
};

test('have all the same properties', () => {
	expect(can1).toEqual(can2);
});

모의(mock) 함수

Jest는 모의(mock) 함수를 생성하고 관리하는 기능을 제공한다.
모의 함수를 사용하여 특정 함수의 동작을 재현하거나 테스트할 때 예상 결과를 설정할 수 있다.
jest - Mock Functions

예를 들어, 외부 API 호출을 테스트하는 경우, 실제 API를 호출하지 않고 모의 함수를 사용해 그 결과를 재현할 수 있다.

// 실제 API 호출 대신 모의 함수 사용
const fetchData = async () => {
  // 외부 API 호출 대신 가짜 데이터 반환
  return { data: 'sample data' };
};

test('fetchData returns sample data', async () => {
  // fetchData를 모의하고 가짜 데이터를 반환하도록 설정
  fetchData.mockResolvedValue({ data: 'sample data' });

  const result = await fetchData();
  expect(result.data).toBe('sample data');
});

테스팅 라이브러리와 테스트 러너의 개념과
React Testing Library, Jest가 무엇인지도 이해했으니 다음에는 진짜로 테스트 코드를 짜보도록 하자!

profile
블로그 이전 -> https://janechun.tistory.com

1개의 댓글

comment-user-thumbnail
2023년 8월 13일

테스트코드는 cypress를 사용해서 조금 작성해본 경험밖에 없었는데, Jest와 테스팅에 대해서 좀 더 공부할 수 있었네요! 도움이 되었습니다!

답글 달기