• [React] React Testing Library(RTL)와 Jest

    2023. 11. 7.

    by. 지은이: 김지은

    728x90

    1. React Testing Library

    create-react-app은 기본적으로 테스트를 위한 환경을 제공한다.

    그래서 터미널에 npm start 말고 npm test를 입력하면 아래처럼 감시모드가 실행이된다. (종료는 q)

     

    src 폴더 안에 App.test.js 파일이 생성됐을텐데 이게 바로 npm test를 실행했을 때 실행되던 테스트파일이다.

    import { render, screen } from '@testing-library/react';
    import App from './App';
    
    test('renders learn react link', () => {
      render(<App />);
      const linkElement = screen.getByText(/learn react/i);
      expect(linkElement).toBeInTheDocument();
    });

     

    render메서드와 screen 객체는 testing-library/react 패키지를 통해서 가져오는데 이는 테스트 작성을 위한 유틸리티 기능을 제공하는 라이브러리이다.

    먼저 render 메서드는 JSX를 이용해서 가상 DOM을 생성하는데 여기성 App컴포넌트를 가상 DOM에 렌더링한다.

    다음 getByTextscreen객체에의 메서드로, 표시괸 모든 텍스트를 기반으로 DOM에서 요소를 찾는다.

    여기선 정규표현식을 사용해서 'learn react' 를 포함하는 요소를 찾는데 'i' 플래그를 사용해서 대소문자를 구분하지 않도록 설정했다.

    마지막은 Assertion인데 linkElement가 문서에 존재하는지를 확인. 즉, 'learn react' 텍스트가 화면에 렌더링 되었는지 확인한다.

    자세한 Assertion은 여기서 확인

     

    function App() {
      return (
        <div className="App">
          ...
          Learn React
        </div>
      );
    }
    
    export default App;

    App컴포넌트에서 찾는 요소는 바로 위 코드와 같이 App.js에 있는 'Learn React' 문자열이다.

    따라서 test 파일에서 'learn react' 으로 작성한 문자열을 다른 문자로 변경하면 App컴포넌트에서 변경한 문구를 찾을 수 없어서

    테스트는 실패해야한다.

     

    test("renders learn react link", () => {
      render(<App />);
      const linkElement = screen.getByText(/learn testing library/i); // 문자열 변경
      expect(linkElement).toBeInTheDocument();
    });


    TestingLibraryElementError: Unable to find an element with the text: /learn testing library/i. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

     

    2. Jest

    RTL은 위처럼 render 메서드로 컴포넌트를 가상 DOM으로 렌더링 할 수 있고, getByText 메서드처럼 가상 DOM을 찾을 수 있다.

    하지만 테스트를 찾고 실행하면서 Assertion을 수행할 테스트 러너가 필요한데 이때 JEST를 사용한다.

     

    package.json에 scripts 안에 test를 실행하면 react-scripts test를 실행하게 되는 것.

    "scripts": {
        "test": "react-scripts test",
     },

     

    그래서 npm test를 실행하면 위 처럼 Jest는 감시 모드(Watch Mode)로 실행된다.

    Jest의 감시모드는 파일이 변경될 때 해당 파일과 관련된 테스트를 다시 실행해서 실시간으로 변경사항에 대한 테스트 결과를 확인할 수 있다.

     

    다시 npm test로 실행하고 아까 변경한 learn testing library 문자열 정규표현식 대신 'Learn React' 를 입력 후 저장하면

    테스트가 재실행되면서 통과가 되는 걸 볼 수 있다.

     

    3. Jest의 원리

    테스트가 통과되거나 실패하는 걸 Jest는 어떻게 알 수 있을까?

     

    Jest의 전역 테스트 메서드는 첫 번째 매개변수로 설명(또는 테스트 케이스)를 받는다. 이 설명 문자열은 테스트가 어떤 동작을 수행하는지 설명한 것으로, 테스트가 실패했을 때 어떤 테스트가 실패했는지를 알려준다.

     

    두 번째 매개변수는 테스트 함수로, Jest는 이 함수를 실행해서 테스트의 성공 또는 실패를 결정한다.

    이 함수가 에러를 발생시키면서 해당 테스트트 실패하게 되고 Jest는 Assertion이 예상과 다르게 동작할 때 에러를 발생시켜 테스트를 실패로 간주한다. 따라서 테스트 함수에 에러가 없으면 테스트는 통과한다.

     

    test('adds 1 + 2 = 3', () => { // 설명
      expect(sum(1, 2)).toBe(3); // Jest 테스트 함수
    });

     

     

     

    댓글