테스트 해보기
jest 를 설치한다. (기존에 있는 서비스에 테스트를 붙이는 방식)
D:\code\node\lecture>npm i -D jest
added 238 packages, changed 4 packages, and audited 504 packages in 16s
44 packages are looking for funding
run `npm fund` for details
처음 상태에서 test를 실행하면 아래와 같이 test가 없다고 나온다.
D:\code\node\lecture>npm test
> nodebird@0.0.1 test
> jest
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In D:\code\node\lecture
20 files checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 0 matches
testPathIgnorePatterns: \\node_modules\\ - 20 matches
testRegex: - 0 matches
Pattern: - 0 matches
test 파일을 만들 때는 test나 spec 이 들어가게 만들면 된다.
index.test.js 파일을 만들고 다시 test를 수행하면 index.test.js 는 찾았는데 테스트가 없다고 나온다.
D:\code\node\lecture>npm test
> nodebird@0.0.1 test
> jest
FAIL middlewares/index.test.js
● Test suite failed to run
Your test suite must contain at least one test.
at onResult (node_modules/@jest/core/build/TestScheduler.js:133:18)
at node_modules/@jest/core/build/TestScheduler.js:254:19
at node_modules/emittery/index.js:363:13
at Array.map (<anonymous>)
at Emittery.emit (node_modules/emittery/index.js:361:23)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.972 s
Ran all test suites.
test 문법은 첫번째는 test의 설명이고, 그 다음은 실제로 어떤 일을 할지 입력한다.(코드와 결과값을 입력한다.)
// index.test.js 파일 내용
test("1+1 은 2입니다.", () => {
expect(1 + 1).toEqual(2);
});
위와 같이 입력 후 테스트를 실행하면 성공했다고 출력 된다.
D:\code\node\lecture>npm test
> nodebird@0.0.1 test
> jest
PASS middlewares/index.test.js
√ 1+1 은 2입니다. (4 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.692 s
Ran all test suites.
expect 를 여러개 한번에 사용도 가능하다.
expect(res.status).toBeCalledWith(403);
expect(res.send).toBeCalledWith("로그인 필요");
index.test.js 를 작성하고 아래처럼 test를 수행해보면 성공한 것을 확인해볼 수 있다.
// middlewares/index.test.js 파일 내용
const { isLoggedIn, isNotLoggedIn } = require("./");
describe("isLoggedIn", () => {
const res = {
status: jest.fn(() => res),
send: jest.fn(),
};
const next = jest.fn();
test("로그인 되어있으면 isLoggedIn이 next를 호출해야 함", () => {
const req = {
isAuthenticated: jest.fn(() => true),
};
isLoggedIn(req, res, next);
expect(next).toBeCalledTimes(1);
});
test("로그인 되어있지 않으면 isLoggedIn이 에러를 응답해야 함", () => {
const req = {
isAuthenticated: jest.fn(() => false),
};
isLoggedIn(req, res, next);
expect(res.status).toBeCalledWith(403);
expect(res.send).toBeCalledWith("로그인 필요");
});
});
describe("isNotLoggedIn", () => {
const res = {
redirect: jest.fn(),
};
const next = jest.fn();
test("로그인 되어있으면 isNotLoggedIn이 에러를 응답해야 함", () => {
const req = {
isAuthenticated: jest.fn(() => true),
};
isNotLoggedIn(req, res, next);
const message = encodeURIComponent("로그인한 상태입니다.");
expect(res.redirect).toBeCalledWith(`/?error=${message}`);
});
test("로그인 되어있지 않으면 isNotLoggedIn이 next를 호출해야 함", () => {
const req = {
isAuthenticated: jest.fn(() => false),
};
isNotLoggedIn(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
});
});
결과화면
D:\code\node\lecture>npm test
> nodebird@0.0.1 test
> jest
PASS middlewares/index.test.js
isLoggedIn
√ 로그인 되어있으면 isLoggedIn이 next를 호출해야 함 (4 ms)
√ 로그인 되어있지 않으면 isLoggedIn이 에러를 응답해야 함 (3 ms)
isNotLoggedIn
√ 로그인 되어있으면 isNotLoggedIn이 에러를 응답해야 함 (1 ms)
√ 로그인 되어있지 않으면 isNotLoggedIn이 next를 호출해야 함 (1 ms)
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 2.022 s
Ran all test suites.
DB에서 불러오는 파일들은 jes.mock 을 통해서 가짜로 변경해서 테스트를 진행할 수 있다.
mockReturnValue 사용.
// user.js 에 있는 내용
const User = require('../models/user');
// user.test.js 에 있는 내용
jest.mock("../models/user");
test("사용자를 찾아 팔로잉을 추가하고 success를 응답해야 함", async () => {
User.findOne.mockReturnValue({
addFollowing(id) {
return Promise.resolve(true);
},
});
await follow(req, res, next);
expect(res.send).toBeCalledWith("success");
});
user.test.js 작성한 후에 테스트 결과 화면
D:\code\node\lecture>npm test
> nodebird@0.0.1 test
> jest
PASS middlewares/index.test.js
PASS controllers/user.test.js
● Console
console.error
DB에러
11 | }
12 | } catch (error) {
> 13 | console.error(error);
| ^
14 | next(error);
15 | }
16 | };
at error (controllers/user.js:13:13)
at Object.<anonymous> (controllers/user.test.js:36:5)
Test Suites: 2 passed, 2 total
Tests: 7 passed, 7 total
Snapshots: 0 total
Time: 3.428 s
Ran all test suites.
테스트 커버리지 살펴보기
package.json 에 아래와 같이 추가하고 실행 결과는 아래와 같다.
test 파일을 만든 것 중에서 얼마나 테스트가 되었는지 확인 가능하다.
"scripts": {
"start": "nodemon app",
"test": "jest",
"coverage": "jest --coverage"
},
D:\code\node\lecture>npm run coverage
> nodebird@0.0.1 coverage
> jest --coverage
PASS middlewares/index.test.js
PASS controllers/user.test.js
● Console
console.error
DB에러
11 | }
12 | } catch (error) {
> 13 | console.error(error);
| ^
14 | next(error);
15 | }
16 | };
at error (controllers/user.js:13:13)
at Object.<anonymous> (controllers/user.test.js:36:5)
-------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------|---------|----------|---------|---------|-------------------
All files | 84 | 100 | 60 | 84 |
controllers | 100 | 100 | 100 | 100 |
user.js | 100 | 100 | 100 | 100 |
middlewares | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
models | 33.33 | 100 | 0 | 33.33 |
user.js | 33.33 | 100 | 0 | 33.33 | 5-47
-------------|---------|----------|---------|---------|-------------------
Test Suites: 2 passed, 2 total
Tests: 7 passed, 7 total
Snapshots: 0 total
Time: 2.246 s, estimated 4 s
Ran all test suites.
통합 테스트
통합 테스트를 위해서 supertest를 설치한다.
D:\code\node\lecture>npm i -D supertest
added 24 packages, changed 5 packages, and audited 528 packages in 5s
52 packages are looking for funding
run `npm fund` for details
테스트를 위해 DB 설정을 해주고 아래와 같이 db 를 생성해준다.
D:\code\node\lecture>npx sequelize db:create --env test
Sequelize CLI [Node: 20.16.0, CLI: 6.4.1, ORM: 6.29.0]
Loaded configuration file "config\config.json".
Using environment "test".
Database nodejs_test created.
routes/auth.test.js 파일에 test 내용을 작성해주고 실행하면 아래와 같이 결과를 알려준다.
D:\code\node\lecture>npm test
> nodebird@0.0.1 test
> jest
PASS middlewares/index.test.js
PASS controllers/user.test.js
......
POST /auth/join 302 342.534 ms - 23
POST /auth/login 302 249.889 ms - 23
POST /auth/join 302 14.069 ms - 115
POST /auth/login 302 3.168 ms - 136
POST /auth/login 302 242.653 ms - 23
POST /auth/login 302 245.272 ms - 154
POST /auth/login 302 246.092 ms - 23
GET /auth/logout 403 2.080 ms - 16
POST /auth/login 302 7.814 ms - 115
GET /auth/logout 302 6.094 ms - 23
PASS routes/auth.test.js (7.015 s)
● Console
......
Test Suites: 3 passed, 3 total
Tests: 14 passed, 14 total
Snapshots: 0 total
Time: 8.013 s
Ran all test suites.
부하테스트를 위해 artillery를 설치해준다.
D:\code\node\lecture>npm i -D artillery
실제 수행을 해본다.
100명이 50번씩 수행한다는 의미 (—count 100 -n 50)
D:\code\node\lecture>npx artillery quick --count 100 -n 50 http://localhost:8001
Test run id: t5xdb_xrpacx8tc4mh993pg9jp357yby3m4_mta3
Phase started: unnamed (index: 0, duration: 1s) 02:08:04(+0900)
Phase completed: unnamed (index: 0, duration: 1s) 02:08:05(+0900)
--------------------------------------
Metrics for period to: 02:08:10(+0900) (width: 5.328s)
--------------------------------------
http.codes.200: ................................................................ 3129
http.downloaded_bytes: ......................................................... 11195562
http.request_rate: ............................................................. 608/sec
http.requests: ................................................................. 3229
http.response_time:
min: ......................................................................... 23
max: ......................................................................... 261
mean: ........................................................................ 151.7
median: ...................................................................... 147
p95: ......................................................................... 198.4
p99: ......................................................................... 214.9
http.responses: ................................................................ 3129
vusers.created: ................................................................ 100
vusers.created_by_name.0: ...................................................... 100
--------------------------------------
Metrics for period to: 02:08:20(+0900) (width: 2.594s)
--------------------------------------
http.codes.200: ................................................................ 1871
http.downloaded_bytes: ......................................................... 6694438
http.request_rate: ............................................................. 689/sec
http.requests: ................................................................. 1771
http.response_time:
min: ......................................................................... 23
max: ......................................................................... 188
mean: ........................................................................ 128.2
median: ...................................................................... 133
p95: ......................................................................... 162.4
p99: ......................................................................... 179.5
http.responses: ................................................................ 1871
vusers.completed: .............................................................. 100
vusers.failed: ................................................................. 0
vusers.session_length:
min: ......................................................................... 6934.4
max: ......................................................................... 7363.9
mean: ........................................................................ 7174
median: ...................................................................... 7117
p95: ......................................................................... 7407.5
p99: ......................................................................... 7407.5
All VUs finished. Total time: 9 seconds
--------------------------------
Summary report @ 02:08:14(+0900)
--------------------------------
http.codes.200: ................................................................ 5000
http.downloaded_bytes: ......................................................... 17890000
http.request_rate: ............................................................. 649/sec
http.requests: ................................................................. 5000
http.response_time:
min: ......................................................................... 23
max: ......................................................................... 261
mean: ........................................................................ 142.9
median: ...................................................................... 141.2
p95: ......................................................................... 194.4
p99: ......................................................................... 210.6
http.responses: ................................................................ 5000
vusers.completed: .............................................................. 100
vusers.created: ................................................................ 100
vusers.created_by_name.0: ...................................................... 100
vusers.failed: ................................................................. 0
vusers.session_length:
min: ......................................................................... 6934.4
max: ......................................................................... 7363.9
mean: ........................................................................ 7174
median: ...................................................................... 7117
p95: ......................................................................... 7407.5
p99: ......................................................................... 7407.5
D:\code\node\lecture>
loadtest.json에 주로 사용될 만한 시나리오를 작성해서 부하 테스트도 가능하다.
결과는 아래와 같다.
D:\code\node\lecture>npx artillery run loadtest.json
Test run id: tqepa_rt48nfkae5zb6xp6jynb53p6x4y6w_a3jj
Phase started: unnamed (index: 0, duration: 30s) 02:33:04(+0900)
--------------------------------------
Metrics for period to: 02:33:10(+0900) (width: 4.575s)
--------------------------------------
http.codes.200: ................................................................ 182
http.codes.302: ................................................................ 91
http.downloaded_bytes: ......................................................... 616343
http.request_rate: ............................................................. 71/sec
http.requests: ................................................................. 273
http.response_time:
min: ......................................................................... 2
max: ......................................................................... 45
mean: ........................................................................ 3.7
median: ...................................................................... 3
p95: ......................................................................... 6
p99: ......................................................................... 13.1
http.responses: ................................................................ 273
vusers.completed: .............................................................. 91
vusers.created: ................................................................ 91
vusers.created_by_name.0: ...................................................... 91
vusers.failed: ................................................................. 0
vusers.session_length:
min: ......................................................................... 12.9
max: ......................................................................... 112.9
mean: ........................................................................ 22.1
median: ...................................................................... 16.9
p95: ......................................................................... 51.9
p99: ......................................................................... 67.4
--------------------------------------
Metrics for period to: 02:33:20(+0900) (width: 9.95s)
--------------------------------------
http.codes.200: ................................................................ 400
http.codes.302: ................................................................ 200
http.downloaded_bytes: ......................................................... 1354600
http.request_rate: ............................................................. 60/sec
http.requests: ................................................................. 600
http.response_time:
min: ......................................................................... 1
max: ......................................................................... 10
mean: ........................................................................ 2.9
median: ...................................................................... 3
p95: ......................................................................... 4
p99: ......................................................................... 6
http.responses: ................................................................ 600
vusers.completed: .............................................................. 200
vusers.created: ................................................................ 200
vusers.created_by_name.0: ...................................................... 200
vusers.failed: ................................................................. 0
vusers.session_length:
min: ......................................................................... 10.5
max: ......................................................................... 37
mean: ........................................................................ 14.2
median: ...................................................................... 13.6
p95: ......................................................................... 17.6
p99: ......................................................................... 27.4
Phase completed: unnamed (index: 0, duration: 30s) 02:33:34(+0900)
--------------------------------------
Metrics for period to: 02:33:30(+0900) (width: 9.952s)
--------------------------------------
http.codes.200: ................................................................ 400
http.codes.302: ................................................................ 200
http.downloaded_bytes: ......................................................... 1354600
http.request_rate: ............................................................. 60/sec
http.requests: ................................................................. 600
http.response_time:
min: ......................................................................... 1
max: ......................................................................... 6
mean: ........................................................................ 2.7
median: ...................................................................... 3
p95: ......................................................................... 4
p99: ......................................................................... 5
http.responses: ................................................................ 600
vusers.completed: .............................................................. 200
vusers.created: ................................................................ 200
vusers.created_by_name.0: ...................................................... 200
vusers.failed: ................................................................. 0
vusers.session_length:
min: ......................................................................... 10.3
max: ......................................................................... 18.8
mean: ........................................................................ 12.9
median: ...................................................................... 12.6
p95: ......................................................................... 16
p99: ......................................................................... 17.6
--------------------------------------
Metrics for period to: 02:33:40(+0900) (width: 5.493s)
--------------------------------------
http.codes.200: ................................................................ 218
http.codes.302: ................................................................ 109
http.downloaded_bytes: ......................................................... 738257
http.request_rate: ............................................................. 71/sec
http.requests: ................................................................. 327
http.response_time:
min: ......................................................................... 1
max: ......................................................................... 6
mean: ........................................................................ 2.5
median: ...................................................................... 2
p95: ......................................................................... 4
p99: ......................................................................... 4
http.responses: ................................................................ 327
vusers.completed: .............................................................. 109
vusers.created: ................................................................ 109
vusers.created_by_name.0: ...................................................... 109
vusers.failed: ................................................................. 0
vusers.session_length:
min: ......................................................................... 9.9
max: ......................................................................... 17.6
mean: ........................................................................ 12.1
median: ...................................................................... 11.8
p95: ......................................................................... 14.4
p99: ......................................................................... 15.3
All VUs finished. Total time: 31 seconds
--------------------------------
Summary report @ 02:33:36(+0900)
--------------------------------
http.codes.200: ................................................................ 1200
http.codes.302: ................................................................ 600
http.downloaded_bytes: ......................................................... 4063800
http.request_rate: ............................................................. 71/sec
http.requests: ................................................................. 1800
http.response_time:
min: ......................................................................... 1
max: ......................................................................... 45
mean: ........................................................................ 2.9
median: ...................................................................... 3
p95: ......................................................................... 4
p99: ......................................................................... 6
http.responses: ................................................................ 1800
vusers.completed: .............................................................. 600
vusers.created: ................................................................ 600
vusers.created_by_name.0: ...................................................... 600
vusers.failed: ................................................................. 0
vusers.session_length:
min: ......................................................................... 9.9
max: ......................................................................... 112.9
mean: ........................................................................ 14.6
median: ...................................................................... 13.1
p95: ......................................................................... 19.9
p99: ......................................................................... 49.9