본문 바로가기
React를 같이 배워보자

React15일차-CRA -UnitTest(jest)

by 멈추지않아 2022. 2. 4.

이제 create-react-app에서 test를 해보겠습니다.

creat-react-app만들어주시고 터미널에서 npm test 해주세요

여기서 a눌러주세요

기본적으로 한개가 있어서 그것이 자동으로 실행되겠습니다.

src/App/test.js가 테스트 파일입니다 그럼 우선 component파일 만들어주시고Button.jsx만들어주세요

import { useEffect, useRef, useState } from "react";
const Button_text = {
  normal: "버튼이 눌리지 않았다.",
  clicked: "버튼이 방금 눌렸다.",
};

export default function Button() {
  const timer = useRef();
  const [message, setMessage] = useState(Button_text.normal);
  useEffect(() => {
    return () => {
      if (timer.current) clearTimeout(timer.current);
    };
  }, []);
  return (
    <div>
      <p>{message} </p>
      <button disabled={message === Button_text.clicked} onClick={click}>
        button
      </button>
    </div>
  );
  function click() {
    setMessage(Button_text.clicked);
    timer.current = setTimeout(() => {
      setMessage(Button_text.normal);
    }, 5000);
  }
}
이렇게 안에 내용을 채워주세요 이거는 테스트할 기본 틀이고 모를만한것들 하나씩 설명해드리겠습니다.
우선 timer.current 이걸 왜쓰는지 의문일꺼에요  버튼이 5초있다가 무슨 역할을 하느데 5초가 되기전에 프로그램이 종료되면 그게 계속 남아있으니까 곤란하잖아요?? 그래서 timer.current에 저장했다가. useEffect를 이용해서 프로그램이 종료되기전에 5초기다리는걸 빨리 끝내 버리는 겁니다.
disabled={message === Button_text.clicked} 이부분은 {}여기 사이에 값이 true이면 disabled가 적용이 되는겁니다. 만약 false이면 disabled 는 적용이 되지 않습니다.
그럼 이제 테스트 파일을 만들어 보겠습니다. component/ex.test.js만들어주세요
/* eslint-disable testing-library/render-result-naming-convention */
import { act, fireEvent, render } from "@testing-library/react";
import Button from "./Button";
describe("버튼 컴포넌트", () => {
  it("컴포넌트 정상 동작", () => {
    const button = render(<Button />);
    expect(button).not.toBe(null);
  });
});
이렇게 작성해주세요
test()는 it() 이걸로 바꿀수 있으므로 test대신 it이 쓰여습니다.
그리고 descripe는 test or it을 하나로 묶어서 편하게 관리하기 위한 상위개체 라고 생각 하시면 편합니다.
describe("요약",()=>{itortest})이렇게 형식은 test와 비슷합니다.

이거 Button컴포넌트가 제대로 render되는지 즉 화면에 제대로 올라가는지알아 보는거입니다.

변수에 render(컴포넌트)를 저장하고 그변수를 expect에 넣으면  잘 작도되는지 확인하게 됩니다.

그렇게 된다면 결과가 빈공간은 아니겠죠??

 그래서 앞에 not을 넣으면 아니다 라는 뜻을 가지게 됩니다.

그래서 해석을 해보면 버튼 컴포넌트를 뛰웠는데 빈공간이 아니지? 라고 테스트 하는겁니다.

빈공가이 아니고 잘올라갔으면 

성공

일허게 제대로 동작이 될것입니다. 이제  Button컴포넌트가 제대로 올라간것을 확인했습니다. 다음은

describe("버튼 컴포넌트", () => {
  it("htmlbuttonelement", () => {
    const { getByText } = render(<Button />);
    const buttonElement = getByText("button");
    expect(buttonElement).toBeInstanceOf(HTMLButtonElement);
  });
});
이렇게 describe안에 it부분 만 바꺼주세요.
 이건 안에 내용이 button이 요소가 HTML의 button요소인지 확인하는것입니다.
const buttonElement = getByText("button"); 이걸로 안에 내용이 button인 것을 찾고
그걸 이용해서 button이 맞는지 확인하는 겁니다.
이렇게 트루 로 나옵니다.

jsx가서 보니까 button이 맞군요

또 변경하겠습니다

describe("버튼 컴포넌트", () => {
  it("버튼클릭시 글자변경", () => {
    const { getByText } = render(<Button />);
    const buttonElement = getByText("button");
    fireEvent.click(buttonElement);
    const p = getByText("버튼이 방금 눌렸다.");
    expect(p).not.toBeNull();
    expect(p).toBeInstanceOf(HTMLParagraphElement);
  });
});

이건 클릭시 글자가  변경 됬는지 확인하는 겁니다.기본적으로

Button_text.normal이거때문에 버튼이 눌리지 않았다. 이지만 클릭시 변하게 된다
함수로 정의 되어있다.

즉 버튼이 방금 눌렸다. 라는 내용이 있는 요소를 찾고 p에 저장한다. 변했다면 저장했을꺼고 없다면 빈공간 일것이다.

그래서 우선 빈공간이 아닌지 확인 그리고 우리가 만든 p태그안에 들어있는 것이 맞는지 확인하는 것이다. 같은 글자가 다른곳에 들어있을수 있다.

여기가 변한다
성공

다음은 클릭안했을시 알아보자

it("버튼클릭안할시", () => {
    const { getByText } = render(<Button />);
    const p = getByText("버튼이 눌리지 않았다.");
    expect(p).not.toBeNull();
    expect(p).toBeInstanceOf(HTMLParagraphElement);
  });

입력해주자 

클릭 안했으면 기본값으로 버튼이 눌리지 않았다. 일것이다. 그래서 그것으로 가져온 것이 빈공간이 아니고p태그가 맞는지 확인하는 것이다.

성공

  it("버튼클릭시 5초후글자변경", () => {
    jest.useFakeTimers();
    const { getByText } = render(<Button />);
    const buttonElement = getByText("button");
    fireEvent.click(buttonElement);
    act(() => {
      jest.advanceTimersByTime(5000);
    });

    const p = getByText("버튼이 눌리지 않았다.");
    expect(p).not.toBeNull();
    expect(p).toBeInstanceOf(HTMLParagraphElement);
  });

입력

이건 5초후에 글자가 다시 원상태로 돌아오는 지 확인하는것이다.

settimeout으로 5000이라는 옵션을 넣어서 5초후에 변하게 해놓았다. 그런데 테스트를 바로 확인하면 안바뀐상태로 확인이 될것이다. 그래서 테스트도 5초 기다리게 해야된다.jest.useFakeTimers(); 이걸 위에 넣어주고

 act(() => {
      jest.advanceTimersByTime(5000);
    });

이렇게 act안에 5000을 적어주면 5초 기다렸다가 테스트를 한다.

그리고 순서가 중요하다 클릭하기전에 기다리면안되고 const p = getByText("버튼이 눌리지 않았다.");이걸하고나서 찾으면

당연히 바뀌기 전에 찾아서 빈공간이 된다. 그래서 5초기다리고 나서 찾게  뒤에 적어줘야한다.

성공

  it("버트비활성화5초", () => {
    jest.useFakeTimers();
    const { getByText } = render(<Button />);
    const buttonElement = getByText("button");
    fireEvent.click(buttonElement);
    expect(buttonElement).toBeDisabled();
    act(() => {
      jest.advanceTimersByTime(5000);
    });

    expect(buttonElement).not.toBeDisabled();
  });

작성 

이건 버튼이 disabled되게 하는것이다. 즉 버튼누르고 5초동안 버튼을 더못누르게 하는것이다.

그런데 같은 시간대에 같이 처리해야되는게 있다 바로 5초동안 안에 내용이

Button_text.clicked 이다 그래서 이게 글자이면 disabled 속성을 넣어주고 아니면 빼주고를 하면된다.

즉 이렇게 설정해을 해주면 대괄호 안에가 5초동안만 true가 되므로 disabled가 된다.

다시 test로 돌아오면 누르고 Disabled가 됬는지 확인해주고 5초기다렸다가 Disabled가 아니지 확인해주는 코드 이다.

성공

오늘은 여기까지 test를 알아봤다. ㅎㅎ 다들 고생많았다.

'React를 같이 배워보자' 카테고리의 다른 글

React17일차-Portal,fowardRef  (0) 2022.02.06
React16일차-최적화로 돌리기  (0) 2022.02.05
React15일차-UnitTest(jest)  (0) 2022.02.04
React14일차-ContextAPI  (0) 2022.02.02
React14일차-컴포넌트 간 통신  (0) 2022.02.02