Vitest, React Testing Library를 이용한 테스트 코드 작성하기 (1)

‘가계부를 부탁해’ 프로젝트를 진행하며 작성한 내용입니다.

project-logo

 

새롭게 개인 프로젝트를 진행하면서 다뤘던 기술들에 대해서 기록을 남겨보려 합니다. 오늘은 다섯 번째 주제로, Vitest & React Testing Library로 테스트 코드를 작성해 보았습니다.

프로젝트 보러가기 👉 : 링크

 

목차

1. TDD와 테스트 코드를 작성하는 이유

2. 테스트의 종류와 도구

3. Jest보다 Vitest를 선택한 이유

4. Vitest 환경 설정하기

5. 테스트 코드 작성하기

 


 

1. TDD와 테스트 코드를 작성하는 이유

TDD(Test Driven Development), 테스트 주도 개발이라는 개념을 많이 들어보셨을 텐데요. 테스트 주도 개발이라 함은 간단히 말하자면 사용자 시나리오에 따라 테스트 코드를 먼저 작성한 뒤, 실제 코드를 작성해 나가는 개발 방법론입니다. 실제 코드를 작성하기 전이기에 테스트 코드는 반드시 실패합니다. 실패하는 테스트 코드를 먼저 작성한 뒤, 테스트가 성공하는 실제 코드를 작성하고 리팩토링하는 프로세스를 따르게 됩니다. (Red-Green 테스트)

참고 - TDD란? 테스트주도개발에 대한 편견과 실상, 방법론 : 링크

 

why tddTDD를 하는 이유 – 출처 : udemy (링크)

 

그럼 반드시 테스트 주도 개발을 해야 할까요? 이 부분에 대해서는 장단점을 먼저 짚어보겠습니다.

장점

  1. 코드가 내 손을 벗어나기 전에 가장 빠르게 피드백 받을 수 있다.
  2. 필요한 코드만 작성하기 때문에 오버 엔지니어링을 방지할 수 있다.
  3. 한 번 테스트 코드를 작성해두면, 애플리케이션 코드가 변경되었을 때 다시 테스트 코드를 작성할 필요가 없어 효율적이다.

단점

  1. 테스트 코드를 작성하지 않는 경우에 비해서 초기 비용(시간/리소스) 증가로 인해 생산성 저하가 발생할 수 있다.
  2. 팀원들이 테스트 코드 작성과 TDD에 적응하는 기간이 필요하다.

이렇듯 TDD는 반드시 차용해야 하는 만능 방법론이라기 보다는, 조직과 팀의 상황에 따라 장단점을 비교하여 도입하면 될 것 같습니다.

 

2. 테스트의 종류와 도구

만약 팀에서 TDD를 적용하기로 결정이 되었다면, 테스트 방식에는 어떤 것들이 있고 어떤 도구들을 사용하는지에 대한 지식이 필요하게 될텐데요. 이번에는 테스트의 종류와, 사용하는 도구들에 대해 알아보도록 하겠습니다.

 

type of tests테스트의 종류 – 출처 : udemy (링크)

 

유닛(단위) 테스트 — Unit tests

기능 테스트 — Functional tests

통합 테스트 — Integration tests

인수 테스트 / E2E 테스트 — Acceptance / End to End tests

참고 - 테스트 코드는 왜 만들까? : 링크

 

3. Jest보다 Vitest를 선택한 이유

Jest는 가장 많이 사용되는 테스트용 라이브러리 입니다. React에서는 React Testing Library와 같이 사용하게 되는데요. CRA가 아닌 Vite를 사용하게 될 경우 Vitest가 설정이 더 간편하고 (별도 테스트 설정 파일 대신 vite.config.ts 파일에 설정), Jest보다 속도가 더 빠르다는 장점이 있어 선택했습니다.

- Jest Vitest
문서화 및 참고 자료 다양함 상대적으로 적음
속도 - 상대적으로 빠름
ES Module 사용 설정이 어려움 설정이 쉬움
문법 test(“”, () => {}) it(“”, () => {})

참고 - Vitest 소개 : 링크 / Vitest Config 방법 : 링크

 

4. Vitest 환경 설정하기

먼저 Vite를 사용하여 프로젝트를 생성해줍니다.

$ npm create vite@latest app-name -- --template react-ts
$ cd app-name

프로젝트를 생성하면 생성된 app 폴더 하위에 vite.config.ts 파일이 생성됩니다. 이제 VitestReact Testing Library (react, jest-dom) 를 추가하고 test 설정 코드를 추가합니다.

app-name$ npm install --save-dev vitest
app-name$ npm install --save-dev @testing-library/react
app-name$ npm install --save-dev @testing-library/jest-dom

vite.config.ts

// "reference"를 선언
/// <reference types="vitest" />
/// <reference types="vite/client" />

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  // "test" 객체를 추가하여 설정 코드를 추가
  test: {
    globals: true,
    environment: "jsdom",
    setupFiles: "./setupTest.js", // setupTest.js 파일과 경로를 입력
    css: true, // css 테스트를 하지 않는다면 사용하지 않아도 됨
  },
  resolve: {
    alias: {
      "@": "/src",
    },
  },
});

코드 설명

  1. globals : 테스트 파일에서 전역으로 사용할 변수를 설정합니다. true 로 설정하면 vitest의 globals를 사용할 수 있습니다.
  2. environment : 테스트 환경을 설정합니다. “jsdom” 으로 설정하면 브라우저 환경을 시뮬레이션하는 JSDOM 환경을 사용할 수 있습니다.
  3. setupFiles: 테스트 실행 전에 실행할 파일을 설정합니다. 파일명은 자유롭게 설정하면 됩니다.
  4. css: CSS 테스트를 할지 여부를 설정합니다. true 로 설정하면 CSS 테스트를 수행합니다. 설정하지 않으면 false 로 간주합니다.

 

setupTest.js

import "@testing-library/jest-dom";
import "@testing-library/react";

import { cleanup } from "@testing-library/react";
import { beforeEach, beforeAll, afterEach, afterAll } from "vitest";

beforeAll(() => {});

beforeEach(() => {
  cleanup(); // 이전 테스트에서 실행된 코드를 초기화하는 함수
})

afterEach(() => {});

afterAll(() => {});

코드 설명

  1. beforeAll : 테스트 파일 단위로 전체 테스트 시작 전에 실행할 코드를 작성합니다.
  2. beforeEach : 각 테스트 시작 전에 실행할 코드를 작성합니다.
  3. afterEach : 각 테스트 완료 후에 실행할 코드를 작성합니다.
  4. afterAll : 전체 테스트 완료 후에 실행할 코드를 작성합니다.

 

설정 코드를 모두 작성했다면, 이제 package.json 파일에도 스크립트를 추가해 줍니다.

{
  "name": "client",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    ...
    "test": "vitest --watch"
  },
  ...
}

 

5. 테스트 코드 작성하기

그럼 이제 간단한 샘플 테스트 코드를 작성해보겠습니다. 테스트 코드를 작성할 파일명은 *.test.tsx 형태로 .test를 붙여주어야 합니다. 테스트 코드는 기본적으로 it 명령어로 테스트 단위를 구분하며, render 메소드로 테스트할 컴포넌트를 불러오고, expect 메소드로 테스트 통과 여부를 검증합니다.

/src/tests/Sample.test.tsx

import { expect, it } from "vitest";
import { render, screen } from "@testing-library/react";

it("샘플 테스트", () => {
  render(<h1>샘플 코드입니다.</h1>);
  const sampleHeading = screen.getByRole("heading", {
    name: "샘플 코드입니다.",
  });
  expect(sampleHeading).toBeInTheDocument();
});

코드 설명

  1. vitest로부터 expect와 it 메소드를 import 합니다.
  2. @testing-library/react로부터 render와 screen 메소드를 import 합니다.
  3. it 메소드의 인자로는 테스트 이름 (string), 콜백 함수를 작성합니다.
  4. render 메소드에 렌더링할 컴포넌트 또는 jsx를 작성합니다.
  5. screen.***ByRole 메소드로 렌더링된 내용 중 “샘플 코드입니다.”와 동일한 문자를 가지고 있는 “heading” 요소를 찾아 sampleHeading 엘리먼트에 할당합니다.
  6. expect 메소드로 sampleHeading가 화면에 존재하는지 검증합니다.

 

마지막으로 콘솔 창에서 npm test 명령어를 실행하여 테스트 코드가 실행해 봅니다. 테스트가 성공하면 passed 카운트가, 실패하면 fail 카운트가 증가합니다. (–watch 옵션이 붙은 경우, 테스트 파일이 업데이트되면 자동으로 테스트를 재실행합니다.)

 

result of sample test테스트가 성공했다.

 

만약 렌더링할 컴포넌트에서 TypeScript를 사용한다면,tsconfig.json 파일에 다음 코드를 추가해 줍니다.

{
  "compilerOptions": {
    // ... other options
    "types": ["@testing-library/jest-dom", "vitest/globals"],
    // ... other options
  }
}

참고 - Property ‘toBeInTheDocument’ does not exist on type 에러 : 링크

 

지금까지 테스트 코드를 작성하기 위한 기본적인 지식과 환경 설정을 진행했는데요. 본격적인 테스트 코드 작성은 이어지는 글에서 다뤄보도록 하겠습니다. 🥰

다음 글 - Vitest, React Testing Library를 이용한 테스트 코드 작성하기 (2) : 링크

 

참고하면 좋은 링크

 

태그 Tag : #react #vitest #react-testing-library #vite #tdd