[FedEx 스터디] 테스트

상민·2023년 3월 26일
0

[FedEx] 스터디

목록 보기
5/10
post-thumbnail

테스트

테스트는 개발에서 필수 과정이며 세 단계로 나눌 수 있다.

  • 단위 테스트
    코드의 각 함수가 제대로 작동하는지 확인하기 위한 테스트
  • E2E 테스트
    사용자 상호 작용을 흉내내서 특정 작동이 발생했을 때 적절한 응답을 하는지 확인하기 위한 테스트
  • 통합 테스트
    서로 구분되어 있는 영역이 함께 잘 작동하는지 확인하기 위한 테스트

Next.js를 테스트하는 것은 리액트나 Express 애플리케이션 등을 테스트하는 것과 다르지 않음

Jest → 단위 및 통합 테스트

Cypress → E2E 테스트

Jest를 사용한 단위 테스트와 통합 테스트

$ yarn add -D jest

모듈을 올바르게 변환할 수 있도록 .babelrc 파일을 열어서 다음 내용을 추가한다.

{
	"presets":["next/babel"]
}
  • utils/index.js
    export function cutTextToLength(str, maxLength) {
      return str.length > maxLength ? str.substring(0, maxLength) + '...' : str;
    }

해당함수를 테스트하는 코드를 작성해보자.

  • utils/tests/index.text.js
    import { cutTextToLength } from "../index";
    
    describe("cutTextToLength", () => {
      test("Should cut a string that exceeds 10 characters", () => {
        const initialString = "This is a 34 character long string";
        const cutResult = cutTextToLength(initialString, 10);
        expect(cutResult).toEqual("This is a ...");
      });
    });
  • describe 테스트와 관련된 그룹을 만듬.
  • test 테스트를 선언하고 실행
  • expect 함수의 출력과 예상한 결과를 비교할 때 사용

Jest 만으로는 리액트 컴포넌트를 테스트할 수 없다.

리액트 컴포넌트를 테스트하려면 컴포넌트를 마운트하고 화면에 렌더링해야함.

react-testing-library

$ yarn add @testing-library/react

컴포넌트에 REST API를 호출하는 코드가 있다면, Mock data를 만들어 내용을 채워넣어야 함.

→ 컴포넌트가 화면에 잘 나오는지 확인하는것이 목적이므로 가짜 데이터를 만들어 컴포넌트에 입력을 전달.

react-testing-library의 renderscreen 메소드를 사용하여 컴포넌트를 화면에 렌더링하고 테스팅 할 수 있음.

Cypress

Cypress는 웹 브라우저에서 돌아가는 모든 것을 테스트할 수 있음.

$ yarn add -D cypress
  • package.json
    "scripts": {
      "dev": "next dev",
      "build": "next build",
      "start": "next start",
    	"test": "jest",
    	"cypress": "cypress run"
    },
  • cypress.json
    {
      "baseUrl": "http://localhost:3000"
    }
    cypress가 어디에서 테스트를 실행해야 하는지 알려주는 설정

우선 REST API가 제대로 작동하는지 확인할 테스트를 작성

pages/api에 있는 두 개의 API를 테스트해보자.

  • pages/api/articles.js
    import data from '../../data/articles';
    
    export default (req, res) => {
      res.status(200).json(data);
    };
    게시글 목록을 반환하는 API
  • pages/api/article/index.js
    import data from '../../../data/articles';
    
    export default (req, res) => {
      const id = req.query.id;
      const requestedArticle = data.find((article) => article.id === id);
    
      requestedArticle
        ? res.status(200).json(requestedArticle)
        : res.status(404).json({ error: 'Not found' });
    };
    게시글 ID를 쿼리 인자로 받아서 해당 ID에 해당하는 게시글을 반환하는 API
  • cypress/integration/api.spec.js
    describe("articles APIs", () => {
      test("should correctly set application/json header", () => {
        cy.request("http://localhost:3000/api/articles")
          .its("headers")
          .its("content-type")
          .should("include", "application/json");
      });
    
    	test("should correctly return a 200 status code", () => {
        cy.request("http://localhost:3000/api/articles")
          .its("status")
          .should("be.equal", 200);
      });
    });
    해당 API 응답 HTTP 헤더에 content-type=application/json 정보가 있는지 확인하는 테스트코드. 추가로 응답코드가 200인지도 확인하는 테스트 코드도 추가.
    // API 응답으로 받은 객체 배열을 받으며 각 객체는 반드시 몇가지 속성을 가져야 한다.
    test(`should correctly return a list of articles`, (done) => {
        cy.request("http://localhost:3000/api/articles")
          .its("body")
          .each((article) => {
            expect(article).to.have.keys("id", "title", "body", "author", "image");
            expect(article.author).to.have.keys("id", "name");
            expect(article.image).to.have.keys("url", "author");
            done();
          });
      });
    // 게시글 ID를 주면 해당 게시글을 읽어오는 API 테스트
      test(`should correctly return a an article given an ID`, (done) => {
        cy.request("http://localhost:3000/api/article?id=u12w3o0d").then(
          ({ body }) => {
            expect(body).to.have.keys("id", "title", "body", "author", "image");
            expect(body.author).to.have.keys("id", "name");
            expect(body.image).to.have.keys("url", "author");
            done();
          }
        );
      });
    // ID에 해당하는 게시글이 없으면 404 에러를 반환하는 테스트코드
      test(`should correctly return a 404 status code when an article is not found`, () => {
        cy.request({
          url: "http://localhost:3000/api/article?id=unexistingID",
          failOnStatusCode: false,
        })
          .its("status")
          .should("be.equal", 404);
      });
    위 테스트 코드도 추가.

Cypress는 실제 서버를 대상으로 테스트를 실행하기 때문에 yarn cypress 명령어로 바로 접근이 불가능.

$ yarn add -D start-server-and-test

해당 패키지를 설치해서 해결 가능

  • package.json
    "scripts": {
      "dev": "next dev",
      "build": "next build",
      "start": "next start",
      "test": "jest",
      "cypress": "cypress run",
      "e2e": "start-server-and-test 'yarn build && yarn start' http://localhost:3000 cypress"
    },
    스크립트 추가

yarn e2e 를 명령어를 입력하면 cypress를 통해 E2E 테스트를 할 수 있음.

profile
FE Developer

0개의 댓글