ET네 만물상 프로젝트 복기 - test

DD·2021년 9월 6일
1

우아한 테크캠프

목록 보기
14/14
post-thumbnail

📣 이 시리즈는...

  • 우아한 테크캠프 4기에서 마지막으로 진행한 프로젝트 전체를 복기해본 문서 시리즈입니다.
  • 제가 작성하지 않은 코드도 포함해서 복기했기에, 오류가 있을 수도 있는 개인적인 학습 기록을 위한 문서입니다!

ET네 만물상 - GitHub Repository / 배포 링크

  • 현재 배포 링크는 내부 문제로 API서버가 동작하지 않습니다.. 조만간 해결할 예정..



Test

  • TDD를 경험해보았다.

  • 프로젝트 끝까지 테스트를 신경쓰진 못 했다. 적당한 사용법과, 나중에 오래 운영할 프로젝트라면 TDD가 좋을 거 같다는 느낌?만 받았다..

  • 테스트 주도 개발.

  • 컴포넌트, 유틸 함수 등에 대해 테스트를 먼저 작성하고 그 테스트를 통과하는 코드를 작성하는 방식


왜 테스트를 하는가?

  • 리팩토링/기능 추가 등 소스코드를 추가/변경 할 때 테스트 통과 유무를 통해 문제를 발견할 수 있다

  • 예를 들어 리팩토링을 한 후 테스트가 깨졌다면, 무언가 잘못 된 것이다..




우리팀의 테스트

  • 먼저 TDD라는 걸 경험해보고자 하는게 목적이 컸다.

  • Jset / testing-library 를 사용했다.

  • 초반 마크업을 먼저 작성하고, 그에 대한 테스트를 작성 후, 기능을 붙이면서 테스트 렌더링 관련 테스트를 통과하는지 확인했다

  • 프로젝트를 진행하면서 컴포넌트가 늘어나고, 계속 변경되면서 테스트 주도가 아니라 컴포넌트를 위한 테스트 코드 다듬기를 하는거 같아서 중간부터는 테스트 코드 작성을 하지 않았다.

  • 느낀 바로는, TDD를 위해서는 생각 이상으로 많은 시간을 들여야하고, 설계를 아주 자세하게해야 한다. 데이터 형태나 컴포넌트 트리, 상태관리를 어떻게 할지 (props전달 / 전역 상태 등..)을 모두 고려해야한다.

  • 3주라는 시간 동안, 완성도라는 팀 목표에는 맞지 않는 거 같았고, 테스트를 어떤식으로 하는 거구나 감만 익히는 정도로 경험한 거 같다




Jest

  • 자바스크립트 테스트 프레임워크

  • Test Runner / Test Mathcer / Test Mock 까지 통합으로 제공한다.

testing-library/react

  • Jest에서 react 테스트를 위해 추가적으로 필요한 라이브러리

  • 모든 테스트를 DOM 위주로 진행한다. 즉, 실제 HTML 마크업의 모습이 어떠한지 테스트하기 용이하다 (BEehavior Driven Test)

  • 컴포넌트의 props/state를 조회하지 않고 컴포넌트의 기능이 똑같이 작동한다면, 컴포넌트의 내부 구현 방식이 바뀌어도 테스트가 실패하지 않는다

  • Enzyme 에 비해 필요한 기능만 지원해서 매우 가볍고, 일관적인 테스트 코드 작성을 할 수 있다.

  • src 디렉토리에 setUpTest.js|ts 파일을 생성해야한다




사용법

  • 기본적으로 Given / When / Then 패턴을 많이 사용한다.

예시

// Button.test.ts|tsx

describe("<Button />", () => {
  it("should render component in document", () => {
    // Given
    const handleClick = jest.fn();
    const { container } = render(
      <Button {...buttonProps} onClick={handleClick} />
    );
    const children = screen.queryByText(CHILDREN);

    // When
    fireEvent.click(
      screen.queryByRole("button") || screen.queryByRole("submit")
    );

    // Then
    expect(container).toBeInTheDocument();
    expect(children).toBeInTheDocument();
    expect(handleClick).toHaveBeenCalledTimes(1);
  });
  • 이 테스트는 해당 버튼이 정상적으로 렌더링 되었는지 / 버튼 내의 텍스트는 정상인지 / 정상적으로 클릭 되는지를 테스트한다

  • Given은 테스트를 위해 준비하는 과정으로, 컴포넌트를 렌더하고, 렌더된 버튼 내부 텍스트 값을 가져오는 등의 동작이다

  • When은 실제로 테스트를 진행하는 과정이다. 컴포넌트 렌더나 내부 텍스트의 경우 When의 동작이 필요 없지만, 클릭 이벤트 같은 경우가 이에 해당한다

  • Then은 테스트를 검증하는 과정이다. Given/When의 동작과 실제 예상이 일치하는지 테스트한다.




각종 용어/메소드 설명

describe

  • 여러개의 테스트(it)을 묶는 역할을 한다

it

  • 실제 하나의 테스트 단위를 의미한다.

expect

  • 특정 조건이 충족하는지 확인한다.

  • expect에 검사할 대상을 인자로 넣고 반환하는 객체(JestMatchers)의 메소드를 사용한다.

  • 주로 toBe~ 의 형태를 띄고 있다.

toBeInTheDocument

  • 렌더링 유무를 확인한다.

screen

  • 현재 화면에 대한 메소드를 가지고 있다

queryByRole

  • 현재 화면에서 해당 tag로 DOM을 찾는다

queryByText

  • 현재 화면에서 해당 text를 가진 DOM을 찾는다

queryByTestId

  • data-testid 속성 중 일치하는 컴포넌트를 찾는다
<Wrapper data-testid="test__container"></Wrapper>

fireEvent

  • click 같은 이벤트를 발생시킨다. 이벤트를 발생시킬 돔을 인자로 받는다



커스텀 유틸

const queryClient = new QueryClient();

const AllTheProviders: FC = ({ children }) => {
  return (
    <ThemeProvider theme={theme}>
      <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
    </ThemeProvider>
  );
};

const customRender = (
  ui: ReactElement,
  options?: Omit<RenderOptions, "wrapper">
) => render(ui, { wrapper: AllTheProviders, ...options });

export const expectText = (text: string) => {
  expect(screen.queryByText(text)).toBeInTheDocument();
};

export * from "@testing-library/react";
export { customRender as render };
  • 테스트 코드에서 render가 react-query 관련 에러가 발생해서 그 처리를 위해 따로 작성한 유틸이다.

  • Provider 관련을 함께 묶은 render 유틸이라고 보면 된다! 그 외에는 기존 testing-library와 같다.

profile
기억보단 기록을 / TIL 전용 => https://velog.io/@jjuny546

0개의 댓글