API를 만들 때는 테스트 주도 개발(TDD) 방식으로 이용하는 것이 좋다. 소스 코드를 개발하는 시간보다 유지보수하는 시간이 더 오래 걸리기 때문에 TDD로 개발하면 유지 보수하는 시간을 줄여준다. 물론 처음 개발할 때는 시간이 조금 더 걸리긴 한다.
* 너무 당연한 말이지만 테스트에 필요한 모듈들은 모두 -D (dev dependencies)로 설치하자.
Node에서 TDD를 사용하기 위해서는 mocha, should, superTest가 주로 이용된다.
유닛 테스트에 한해 Jest로 대통합되는 분위기네요 이제...
React는 react testing libary를 쓰고, e2e에는 Enzyme을 쓰는 등 다른 라이브러리도 많이 나오는 편
☕ mocha
mocha는 테스트 코드를 돌려주는 테스트 러너이다. 문서가 그렇게 길지 않으니 한 번 다 읽어보자.
모카는 크게 두 파트로 나뉜다. 테스트 수트와 테스트 케이스.
테스트 수트는 테스트 환경으로, describe()로 구현한다. 테스크 케이스는 실제 테스트를 말하며 it()으로 구현한다.
설치
npm i -g mocha
npm i -D mocha
간단하게 utils.js를 만들고 utils.spec.js에서 테스트해보자. 테스트를 실행하는 sj파일은 spec.js 확장자가 붙는다.
const capitalize = (str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
};
module.exports = {
capitalize: capitalize,
};
// spec.js은 js 테스트 코드를 말합니다.
// specification의 약자입니다.
// 작성한 utils 검증을 위해 import
const utils = require("./utlis");
// node 내장 모듈 assert
const assert = require("assert");
describe("utils.js를 테스트합니다.", () => {
it("문자열의 첫번째 문자를 대문자화", () => {
const result = utils.capitalize("hello");
assert.equal(result, "Hello");
});
});
이후 테스트를 하기 위해서는 package.json의 scripts를 설정한다. npm init를 하면 scripts에 자동으로 있던 test 명령어를 드디어 사용하게 된다.
"scripts": {
//"test": "echo \"Error: no test specified\" && exit 1",
// test를 반복해서 실행하는 것이 귀찮다면 nodemon --exec mocha index.spec.js를 입력
"test": "mocha utils.spec.js",
"start": "nodemon --exec node index --delay 2"
},
npm run test를 돌리면 다음과 같을 결과를 출력한다. 왼쪽은 실패, 오른쪽은 성공
✔ should
express에서는 테스트에서 assert보다 다른 서드 파티 모듈을 사용할 것을 권장하고 있다. 테스트코드에서 검증 라이브러리로 주로 사용되는 것이 should이다.
설치
npm i -D should
위의 utils.spec.js에서 assert를 should로 교체했습니다.
// spec.js은 js 테스트 코드를 말합니다.
// specification의 약자입니다.
const utils = require("./utlis");
const should = require("should");
describe("utils.js를 테스트합니다.", () => {
it("문자열의 첫번째 문자를 대문자화", () => {
const result = utils.capitalize("hello");
result.should.be.equal("Hello");
});
});
🦸 superTest
단위 테스트 : 함수의 기능 테스트
통합 테스트 : API 기능 테스트
지금까지 작성한 건 대문자화를 하는 함수를 테스트한 것이므로 단위 테스트이다. superTest는 익스프레스 통합 테스트용 모듈이다. 내부적으로 익스프레스 서버를 구동시켜 시나리오대로 실제 요청을 보낸 뒤 결과를 검증한다.
위 github에서 제공해준 예시를 살펴보자
const request = require('supertest');
const express = require('express');
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'john' });
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
request를 보면, /user GET을 날리면 Content-Type이 json이고 length 15, 상태 코드는 200번을 받기를 기대(expect)한다. 만약 에러가 있다면 에러를 던지는 걸로 마무리(end) 한다.
간단하다. 바로 사용해보자.
설치
npm i -D supertest
활용
통합 테스트하고자 하는 파일의 spec.js를 만들어 테스트를 돌리면됩니다. 여기서 주의해야 할 것이, 실제로 express 서버를 가동시키는 것이기 때문에 nodemon으로 이미 서버를 돌리고 있다면 꺼야 한다는 것입니다.
(왜 안되는지 계속 해보다가 오류창을 읽어보니 listen EADDRINUSE: address already in use :::3000라고 합니다... 하...)
// index.js
const express = require("express");
const logger = require("morgan");
const app = express();
... 중략
app.listen(PORT, () => console.log(`http://localhost:${PORT}`));
module.exports = app;
여기서 중요한 건 done()의 사용입니다.
Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
// index.spec.js
const app = require("./index");
const request = require("supertest");
describe("Get users를 불러옵니다.", () => {
it("...", (done) => {
request(app)
.get("/users")
.expect(200)
.end((err, res) => {
if (err) {
return done(err);
}
console.log(res.body);
done();
});
});
});
체크한대로 성공했습니다!
'Node, Nest, Deno > 🧪 test (jest, mocha...)' 카테고리의 다른 글
jest (5) : Mock, 외부 패키지 Mock, Spy (0) | 2021.06.18 |
---|---|
jest (4) : Setup and test block scope (0) | 2021.06.18 |
jest (3) : 비동기 코드 테스트하기 (0) | 2021.06.18 |
jest (2) : Matcher 사용하여 테스팅하기 (0) | 2021.06.18 |
jest (1) : installation, configuring (0) | 2021.06.18 |