API를 만들 때는 테스트 주도 개발(TDD) 방식으로 이용하는 것이 좋다. 소스 코드를 개발하는 시간보다 유지보수하는 시간이 더 오래 걸리기 때문에 TDD로 개발하면 유지 보수하는 시간을 줄여준다. 물론 처음 개발할 때는 시간이 조금 더 걸리긴 한다.
* 너무 당연한 말이지만 테스트에 필요한 모듈들은 모두 -D (dev dependencies)로 설치하자.
Node에서 TDD를 사용하기 위해서는 mocha, should, superTest가 주로 이용된다.
유닛 테스트에 한해 Jest로 대통합되는 분위기네요 이제...
React는 react testing libary를 쓰고, e2e에는 Enzyme을 쓰는 등 다른 라이브러리도 많이 나오는 편
☕ mocha
mocha는 테스트 코드를 돌려주는 테스트 러너이다. 문서가 그렇게 길지 않으니 한 번 다 읽어보자.
Mocha - the fun, simple, flexible JavaScript test framework
Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct te
mochajs.org
모카는 크게 두 파트로 나뉜다. 테스트 수트와 테스트 케이스.
테스트 수트는 테스트 환경으로, 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이다.
shouldjs/should.js
BDD style assertions for node.js -- test framework agnostic - shouldjs/should.js
github.com
설치
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
visionmedia/supertest
🕷Super-agent driven library for testing node.js HTTP servers using a fluent API. - visionmedia/supertest
github.com
단위 테스트 : 함수의 기능 테스트
통합 테스트 : 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 |