[TDD] Jest로 NodeJS API 테스트

isTuna·2021년 4월 16일
3

[TDD]

목록 보기
1/1
post-thumbnail

TDD

TDD는 Test Driven Development, 테스트 주도 개발 방법론을 뜻합니다. 테스트 케이스를 먼저 작성한 후에 구현하는 소프트웨어 개발 방법론 중 하나입니다. TDD를 현재 많은 기업에서 사용하고 있는데 먼저 TDD의 장점을 살펴봅시다.

TDD테스트 케이스 작성 -> 코드 구현 => 리펙토링 이라는 짧은 주기를 반복하며 개발합니다. 이를 통해 아래와 같은 이점들이 있습니다.

  • 개발하고 있는 코드의 문제점을 빠르게 알 수 있다.
  • 테스트 코드는 사용설명서 또는 API 문서로서 의사소통 도구로 활용 가능하다.
  • 짧은 주기로 성취감을 얻어 개발자의 능률을 올릴 수 있다.
  • 자동화된 유닛 테스트가 전재가 되어 추가 구현이 용이해진다.

Jest로 API 테스트

위에서 짧게 TDD에 대해 설명했는데 사실 현재 진행하고 있는 프로젝트는 TDD를 따라서 개발하고 있진 않았습니다. 이미 User 생성 및 조회 기능은 만들어졌지만 TDD를 경험해 보고 싶어 뒤늦게라도 테스트를 하기로 했습니다.

제 프로젝트의 기술 스택은 이렇습니다.

  • NodeJS
  • Mongoose
  • Express

NodeJS의 테스트 tool로 Mocha Chai 등 많지만 저는 JestSupertest를 써보기로 했습니다.

먼저 JestSupertest를 설치해보겠습니다.

npm i jest supertest

설치가 완료되면 package.json 파일의 script에 test를 추가하면 됩니다.

"scripts" :{
	"test":"jest" 
}

위와 같이 수정했다면 이제 테스트 케이스를 만들면 됩니다.

user create test

프로젝트 폴더에 test 폴더를 새로 만들고 그 안에 user.test.js 파일을 만들어 줍니다.

저는 초기에는 아래와 같이 만들었습니다.


const request = require('supertest');
const app     = require('../app');

describe('User API Test', () => {
    test('should test that ture === true', () => {
        expect(true).toBe(true);
    });

    test('should create new user', async (done) => {
        const response = await request(app).post('/user')
        .send({
            username: "testName",
            icon    : "http://localhost:3000/",
            tier    : "testTier"
        });
        
        expect(response.status).toEqual(201);
        expect(response.body.success).toEqual(true);
        done();
    });
});

describe 함수는 여러개의 테스트를 묶어주는 역할을 합니다.

expect는 테스트가 해당 조건을 만족하는지 검증하는 함수입니다. 그 종류로는 toEqual,toBe 외에도 많은 검증 방법이 존재합니다.

위의 코드로 테스트를 해보고 싶으면 터미널에서 npm test를 실행하면 됩니다. 하지만 위의 코드를 2번 실행하면 아래와 같은 MongoError: E11000 duplicate key error collection:가 발생할 수 있습니다.

User를 생성할 때 usernameunique로 설정했기 때문에 중복이 존재할 수 없어서 생긴 문제입니다. 그래서 아래와 같은 의문들이 생겼습니다.

  • 유닛 테스트가 나의 개발용 DB를 Hit하는가?
  • 테스트가 끝나는 시점에 DB에서 추가된 내용을 삭제하는가?

찾아본 결과 Jesttestdb에 연결하기 위해선 따로 설정이 필요하다고 합니다. 프로젝트의 config 폴더에 test.env를 만들어 줍시다.

위와 같이 만들어 test를 할 때는 테스트 전용 db에 접근하도록 해야합니다. test.env를 만들었으면 이제는 package.json도 다시 수정해야합니다.

//package.json
"scripts": {
    "start": "node app.js",
    "test": "env-cmd -f ./config/test.env/ jest --watch",
    "dev": "env-cmd -f ./config/dev.env nodemon app.js"
  },

env-cmd는 커맨드에 불러올 .env 파일을 설정하게 해줍니다. npm i env-cmd로 설치해줍시다.

이제 npm test를 실행하면 테스트용 db를 접근하게 됩니다. 하지만 여전히 테스트를 2번 진행하면 duplicate 에러가 발생합니다. 이를 해결하기 위해서는 beforeEach를 사용해야 합니다.

beforeEach

beforeEach는 각 테스트 이전에 실행되는 코드들이 들어있습니다. beforeEach 안에는 테스트 이전에 필요한 데이터를 넣을 수도 ex) 유저 검색 테스트를 위해 유저 생성, 또는 기존의 데이터를 모두 삭제할 수도 있습니다.

그래서 user.test.js에도 아래와 같은 코드를 추가해줍시다.

const User = require('../models/user');

beforeEach( async () => {
    await User.deleteMany({});
});

위의 코드를 추가하고 다시 테스트를 실행하면 성공하는 모습을 확인할 수 있습니다.

마무리

이제야 User API에 테스트를 적용해 봤습니다. 다음에는 다른 API에도 테스트케이스를 적용해보도록 하겠습니다.


profile
청소연구소 개발자 (2021. 05~ )

0개의 댓글