본문 바로가기
코딩 정보/React

[React] Unit Test 에 대해 알아보자

by 꽁이꽁설꽁돌 2024. 8. 30.
728x90
반응형

 

목차

     

    Unit Test란?

    단위 테스트(Unit Test)는 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트이다. 여기서 모듈은 애플리케이션에서 작동하는 하나의 기능 또는 메소드로 이해할 수 있다. 예를 들어 웹 애플리케이션에서 로그인 메소드에 대한 독립적인 테스트가 1개의 단위테스트가 될 수 있다.

     

    즉, 단위 테스트는 애플리케이션을 구성하는 하나의 기능이 올바르게 동작하는지를 독립적으로 테스트하는 것으로, "어떤 기능이 실행되면 어떤 결과가 나온다" 정도로 테스트를 진행한다.

     

     

     

    Unit Test의 장점

    일반적으로 실무에서 테스트 코드를 작성한다고 하면 거의 단위 테스트를 의미한다. 통합 테스트는 실제 여러 컴포넌트들 간의 상호작용을 테스트하기 때문에 모든 컴포넌트들이 구동된 상태에서 테스트를 하게 된다. 그렇기에 통합 테스트를 위해서는 캐시나 데이터베이스 등 다른 컴포넌트들과 실제 연결을 해야 하고, 시스템을 구성하는 컴포넌트들이 많아질수록 테스트를 위한 비용(시간)이 상당히 커진다. 반면에 단위 테스트는 해당 부분만 독립적으로 테스트하기 때문에 어떤 코드를 리팩토링하여도 빠르게 문제 여부를 확인할 수 있다.

    • 테스팅에 대한 시간과 비용을 절감할 수 있다.
    • 새로운 기능 추가 시에 수시로 빠르게 테스트 할 수 있다.
    • 리팩토링 시에 안정성을 확보할 수 있다.
    • 코드에 대한 문서가 될 수 있다.

    그렇기 때문에 실무에서는 단위 테스트를 선호하며, 요즘 많이 사용되는 TDD(Test-Driven Development, 테스트 주도 개발) 에서 얘기하는 테스트도 단위 테스트를 의미한다. 우리는 우리가 작성한 테스트 코드를 수시로 빠르게 돌리면서 문제를 파악할 수 있다. 

     

     

    React에서 Unit Test해보기

    npx-create-react-app을 통해 프로젝트를 시작하면 다음과 같이 파일이 만들어진다.

     

    그러면 render에 내가 test 원하는 컴포넌트를 넣어주자

    단 텍스트 식별로 인해 내가 테스트 하는 코드에는 대소문자 상관없이 learn react가 들어가 있어야 한다.

    import { render, screen } from "@testing-library/react";
    import Unit from "../src/UnitTestProject/Unit";
    
    test("renders learn react link", () => {
      //랜더링 컴포넌트
      render(<Unit />);
      //가상의 화면에 뿌려지게 함
      const linkElement = screen.getByText(/learn react/i);
      //그 안에서 랜더링이 되는지 텍스트로 식별
      expect(linkElement).toBeInTheDocument();
    });

     

    다음 코드를 실행해서 테스트를 진행해 주자

    $ npm test

     

     

    import logo from './logo.svg';
    import './Unit.css';
    
    function Unit() {
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.js</code> and save to reload.
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Learn More
            </a>
          </header>
        </div>
      );
    }
    
    export default Unit;

     

    만약 내가 Learn React를  Learn More로 바꾸게 되면 아래와 같이 실패 이유와 함께 결과가 나온다.

     

    상태를 가진 컴포넌트 unit test

    Greeting.jsx

    import { useState } from "react";
    import Output from "./OutPut";
    export default function Greeting() {
      const [changeText, setChangedText] = useState(false);
    
      function changeTextHandler() {
        setChangedText(true);
      }
    
      return (
        <div>
          <h2>Hello world!</h2>
          {changeText ? (
            <Output>Changed!</Output>
          ) : (
            <Output>It's good to see you!</Output>
          )}
          <button onClick={changeTextHandler}>Change Text!</button>
        </div>
      );
    }

     

    아래와 같이 각 상태가 변할때 별로 테스트 해볼 수 있다.

     

    Greeting.test.js

    import Greeting from "./Greeting";
    import { render, screen } from "@testing-library/react";
    import userEvent from "@testing-library/user-event";
    //여러 test객체 묶어줌
    describe("Greeting component", () => {
    
    //1번 테스트
      test("renders Hello World as a text", () => {
        render(<Greeting />);
    
        //Act
        // ..nothing
        //Assert
        const helloWorldElement = screen.getByText("Hello World", { exact: false });
        expect(helloWorldElement).toBeInTheDocument();
      });
      
      //2번 테스트
      test("renders Not Changed as a text", () => {
        render(<Greeting />);
    
        const NotchangeElement = screen.getByText("It's good to see you!");
        expect(NotchangeElement).toBeInTheDocument();
      });
      
      //3번 테스트
      test("renders Changed as a text", () => {
        render(<Greeting />);
        //버튼이 눌린 후를 확인하고 싶음
        const buttonElemnt = screen.getByRole("button");
        userEvent.click(buttonElemnt);
        const changeElement = screen.getByText("Change Text!");
    
        expect(changeElement).toBeInTheDocument();
      });
    
    });
    
    //Arrange -> 테스트하고자 하는 컴포넌트 랜더링
    //Act -> 실제로 테스트
    //Assert -> 결과 단언 아웃풋이 일치하는가

     

    아래와 같이 테스트가 성공적인 것을 볼 수 있다.

    원래는 test Suits가 하나여야 하는데 나는 테스트를 하나더 해서 2개이다. (테스트도 +1)

     

    반응형