본문 바로가기
BackEnd

Unit Test에 대해 알아보기

by SoriKim 2023. 12. 17.
반응형

📌 Unit Test란?

Unit Test(단위 테스트)는 소프트웨어 개발에서 가장 작은 단위인 "유닛"을 테스트하는 것입니다. 

이 유닛은 일반적으로 함수, 메소드, 또는 클래스와 같은 작은 코드 조각을 나타냅니다. 단위 테스트는 해당 코드 조각이 의도한 대로 작동하는지 확인해 코드의 신뢰성을 높이고 버그를 미리 찾아내는 데 도움을 줍니다. 

 

🔵 단위 테스트의 장점

 

1. 신속한 버그 발견

코드를 변경하거나 업데이트 시 빠르게 테스트 하므로 버그를 초기에 찾아낼 수 있습니다. 

 

2. 코드의 신뢰성 향상

단위 테스트를 통해 코드의 동작이 예상한 대로 되는지 검증해 코드의 신뢰성을 향상시킵니다. 

 

3. 리팩터링 지원

코드를 개선하거나 리팩터링할 때 단위 테스트는 여전히 기능이 제대로 작동하는지 확인하는 데 도움을 줍니다. 

 

4. 문서화 역할

단위 테스트는 코드의 예상 동작을 문서화하고 새로운 개발자에게 코드 이해를 돕는 역할을 합니다. 

 

1. Node.js 환경에서의 단위 테스트 

 

1️⃣ supertest 설치 

# 실행하려는 폴더 내의 터미널에서 아래 명령어 실행
npm i --save-dev supertest

 

2️⃣ 폴더 구조 및 테스트 코드를 위한 필요 작성 코드 

폴더 구조

 

위와 같이 테스트 폴더 구조 참고해 생성 해주세요. 

1. app.js 설정 

// app.js

const express = require("express");
const cors = require("cors");
const morgan = require("morgan");

const { routes } = require("./src/routes");

const createApp = () => {
  const app = express();

  app.use(express.json());
  app.use(cors());
  app.use(morgan("combined"));

  app.use(routes);

  return app;
};

module.exports = { createApp };

 

2. server.js 설정

// server.js

require("dotenv").config();

const { createApp } = require("./app");
const { AppDataSource } = require("./src/models/data-source");

const startServer = async () => {
  const app = createApp();
  const PORT = process.env.PORT;

	await AppDataSource.initialize();

  app.listen(PORT, () => {
    console.log(`Listening on Port ${PORT}`);
  });
};

startServer();

 

3. 테스트용 dotenv 설정

실제 테스트용 dotenv에는 테스트 환경에 맞는 값을 추가해줘야 합니다. 

# .env.test

DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=dbpassword
DB_NAME=dbname

 

4. package.json 내용 추가 

"scripts": {
    "test": "DOTENV_CONFIG_PATH=.env.test jest --setupFiles=dotenv/config"
  },

 

5. Unit Test 작성 예시(회원가입 API) 

// 예제 코드: user.test.js

const request = require("supertest");

const { createApp } = require("../app");

// DB와의 커넥션을 위해 DataSource 객체를 불러오기
const { AppDataSource } = require("../src/models/data-source");

describe("Sign Up", () => {
  let app;

  beforeAll(async () => {
    // 모든 테스트가 시작하기 전(beforeAll)에 app을 만들고, DataSource를 이니셜라이징
    app = createApp();
    await AppDataSource.initialize();
  });

  afterAll(async () => {
    // 테스트 데이터베이스의 불필요한 데이터를 전부 삭제
    await AppDataSource.query(`TRUNCATE users`);

    // 모든 테스트가 끝나게 되면(afterAll) DB 커넥션 끊기
    await AppDataSource.destroy();
  });

  test("FAILED: invalid email", async () => {
    // supertest의 request를 활용하여 app에 테스트용 request 전송
    await request(app)
      .post("/users/signup") // HTTP Method, 엔드포인트 주소를 작성
      .send({ email: "wrongEmail", password: "password002@" }) // body를 작성
      .expect(400) // expect()로 예상되는 statusCode, response를 넣어 테스트 가능
      .expect({ message: "invalid email!" });
  });

  // 다음과 같이 본인이 작성한 코드에 맞춰 다양한 케이스를 모두 테스트 해야 의도에 맞게 코드가 잘 작성되었는지 테스트 단계에서부터 확인
  test("SUCCESS: created user", async () => {
    await request(app)
      .post("/users/signup")
      .send({ email: "dream001@gmail.com", password: "dream001@" })
      .expect(201);
  });

  test("FAILED: duplicated email", async () => {
    await request(app)
      .post("/users/signup")
      .send({ email: "dream001@gmail.com", password: "dream001@" })
      .expect(400)
      .expect({ message: "duplicated email" });
  });
});

 

3️⃣ 테스트 실행

기본 설정과 테스트 코드를 작성한 후 npm test 명령어를 입력해 실행해 보면 아래와 같이 의도한 대로 정상 작동해야 합니다. 

반응형

'BackEnd' 카테고리의 다른 글

SoftWare Test(소프트웨어 테스트)에 대해서 알아보기  (0) 2023.12.26
API 문서에 대해서 알아보기  (0) 2023.12.17
[AWS] VPC에 대해서  (0) 2023.12.06
[AWS] RDS에 대해서  (0) 2023.12.03
CI/CD에 대해서  (0) 2023.12.03

댓글