33Day

김하은·2023년 3월 6일
0

수업 마지막주가 시작된날.


  1. 테스트 코드 작성
  2. 배포

테스트 코드를 만드는 이유

기능없이 테스트를 하는 방식(ttd)

테스트
:마우스로 클릭하는것등을 대신해주는것.(API요청등)
이 대신해주는 코드를 만드는것이 테스트코드

업데이트 배포

모든 기능을 테스트 후 배포를 한다. => 잘 사용하는 중에 이후 기능을 추가를 하기로 하고 어떤 기능을 추가한다.

물론 이 과정에서 추가할 기능의 테스트를 하고, 그후 이 기능을 추가하여 배포를 (업데이트배포)한다.

=> 이후 사용하다가 관련된 다른 기능에서 에러가난다.(물론 추가한 기능은 테스트를 완료하고 추가했으니 문제가 없다. 다만 이 기능들과 관련된 어떤 부분에서 문제가 생겼다

==> 그럼 추가된 기능과 연결된 문제인것인데 어디서 문제가 생겼는지 알 수 없다.

과연 이 에러만 있을까

따라서 기능 하나를 만들때(추가할때) 모든 기능들을 다 테스트 해봐야한다.

테스트 코드가 필요한이유!!

==> 이 모든 기능을 수동으로 테스트 해보기에는 너무 많다.
따라서 서비스 규모가 커질수록 더 테스트를 자동으로 돌려주게하는 테스트 코드가 중요하다.

  • 개별 기능등 단위테스트
  • 여러기능 한꺼번에 하는 통함테스트
  • E2E테스트(시나리오가 있음. 결제 --> 환불 등 과정에 대한 테스트 로직을 짜는것.)

JEST라는 test전용 프레임워크 사용!!


jest설치

yarn add --dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom

=> 네가지가 설치되는데 testing=library/react는

jest.config.ts 라는 파일을 만들고 설정 파일을 복사해 붙여넣는데
해당 설정파일은 next 버전에 맞는 버전이기에 얘도 버전을 12.1.0로 수정하고 다시 yarn install을 한다.

https://nextjs.org/docs/testing#jest-and-react-testing-library

여기를 참고!!!

추가 :

 moduleDirectories: ["node_modules", "<rootDir>/"]
```,

"test": "jest"
로 yarn test시에 jest가 실행되게 실행 명령어도 추가

jest와 esLint 함께 사용하기

jest를 eslint를 함께 사용하기위해서는 추가해줘야 할 내용이 있습니다.

.eslintrc.js 파일로 들어가 아래 내용으로 바꿔주세요!

plugins: ["react","jest/globals"],
"scripts": {
    "test": "jest",
		"test:watch": "jest --watch"
  }
test:watch는 소스코드를 고칠때마다 jest가 실행되길 원하신다면 추가해주시면 됩니다.

만일 추가하지 않으신다면, 원할때마다 `yarn test` 를 입력하셔서 jest를 실행해주셔야 합니다.

UI테스트
// UI테스트 하기

export default function JestUnitTestPage(): JSX.Element {
  return (
    <>
      <div>철수는 13살 입니다</div>
      철수의 취미 입력하기: <input type="text" />
      <button>철수랑 놀러가기</button>
    </>
  );
}


>
>``
import JestUnitTestPage from "../../pages/section33/33-02-jest-unit-test";
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
>
it("내가 원하는데로 그려지는지 테스트 하기", () => {
  render(<JestUnitTestPage />); //  가상돔에 그리기
>
  const myText = screen.getByText("철수는 13살 입니다");
  expect(myText).toBeInTheDocument(); // 돔안에 그려져있는지 기대(그려져 있는지를 봄)
  const myText2 = screen.getByText("철수의 취미 입력하기:");
  expect(myText2).toBeInTheDocument();
  const myText3 = screen.getByText("철수랑 놀러가기");
  expect(myText3).toBeInTheDocument();
});
>

실무에서는 일단 필요한 부분만 테스트를 돌리고, 그중에서 걸리는 것을 따로 또 테스트 코드를 작성하여 돌리는 방식이다.


그럼 일일히 텍스트등을 다 직접 적어서 테스트 코드를 짜야하나?

snapshot

으로 찍어서 비교한다.

import JestUnitTestPage from "../../pages/section33/33-03-jest-unit-test-snapshot";

import { render } from "@testing-library/react";
import "@testing-library/jest-dom";

it("내가 원하는데로 그려지는지 테스트 하기", () => {
  const result = render(<JestUnitTestPage />); //  가상돔에 그리기
  expect(result.container).toMatchSnapshot(); // 스냅샷이랑 다른게있는지 비교, 없으면 사진을 찍어 만듬.
  // 처음 명령어는 yarn test로 없으면 스냅샷을 찍어둠.. 이후 스냅샷 업데이트 된것으로 찍으려면 yarn test -u
});

// 테스트 코드는 정답을 테스트 하는것이 아니라 뭔가 바뀌었을때 알려주는 용도 라고 이해하면 될 듯.


APi테스트해보기

실제 벡엔드가 있어야 할 수 있는것. 따라서 이렇게되면 벡엔드에 의존할 수 밖에 없고, 기능 하나 추가할때마다 그 많은 api를 다 요청하는것은 비효율적.

따라서 모킹을 이용. => 가짜로 만들기.

mocking은 결국 api를 가짜로 만들어야 하기때문에 각각 라이브러리마다 제공해주는 기능이 있다.
-->

yarn add -D msw cross-fetch next-router-mock

Mocking

  1. 화면 랜더링

  2. input창들에 값입력 => fireEvent사용

  3. 등록하기 버튼 클릭 => fireEvent사용

  4. 뮤테이션 날리기 => 가짜 api를 먼저 만들고 실행.(뮤테이션을 날리면 이 가짜가 실행됨. 그리고 result에 결과를 담음.

  5. 등록된 페이지로 이동. => router.push로 이동됨.

==> 최종적 검증 해야하는 부분은 마지막 router.push(/boards/게시물아이디) => 이 부분.


MSW사용: mock-service-worker 설치,cross-fetch 설치

yarn add cross-fetch --dev
yarn add msw --dev
yarn add next-router-mock --dev

가짜 api를 사용하기 위해서 api를 모아둘 수 있는 파일을 새로 만들어줍니다. => commons/mocks/apis.js

위의 api 파일을 사용하기 위해서 서버를 셋팅할 수 있는 js 파일을 동일한 디렉토리 안에 새로 생성 =>

import { setupServer } from "msw/node";
import { apis } from "./apis";
>
// 모킹 데이터를 가짜 서버로 돌릴 수 있도록 설정
export const server = setupServer(...apis);

jest가 실행될 때마다 서버를 그때그때마다 수동으로 작동시키기는 매우 비효율적이므로
jest가 자동으로 서버를 실행시킬 수 있도록 설정이 필요합니다.

상위 디렉토리, jest.config.js와 동일한 경로의 디렉토리 안에 jest.setup.js 파일을 생성한 후
서버를 실행시키는 코드를 새로 추가합니다.

import { server } from "./src/commons/mocks";

beforeAll(() => server.listen());
afterAll(() => server.close());

jest가 서버를 자동으로 실행시킬 수 있도록, jest.config.js에서
jest.setup.js가 서버를 실행시켜주는 파일임을 명시해줘야 합니다.

// jest.config.js

const customJestConfig = {
	...
	...
	...
  // jest 실행시마다 실행되는 셋팅 파일
  setupFilesAfterEnv: ["./jest.setup.js"],
};

eslint가 jest를 감지할 수 있도록
eslintrc.js의 env탭에 jest를 추가해줍니다.

// eslintrc.js

module.exports = {
  env: {
    browser: true,
    es2021: true,
    jest: true,
  },
	...
	...
}

단일테스트: 기능하나를 테스트
통합 // : 기능 여러개 묶어서 테스트
E2E테스트: 사이프레스 라는 도구를 사용해 하는 테스트(next에서 cypress사용하기)

yarn add --dev cypress


TTD => 기능을 만들기 전에 테스트코드 먼저 만들기

Test-Driven-Development , 테스트 주도 개발을 의미합니다. 보통의 개발 과정은 다음과 같습니다. 요구 사항을 정의하고, 디자인이 나오고, 이를 토대로 실제 코드를 작성 하고 테스트를 진행합니다.

하지만 TDD는 테스트 코드를 먼저 작성하고 그 후에 테스트를 통과하기 위한 최소한의 실제 코드를 작성합니다. 그 다음에 코드를 리팩토링합니다.


가장 중요한것은 단일테스트. 이것을 통해 안정적으로 기능을 붙여갈 수있다.

그리고 가장 중요한 API모킹!!!

0개의 댓글