테스트 해보기

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

'Javascript > Node' 카테고리의 다른 글

노드 교과서 섹션 8  (0) 2023.08.23
노드 교과서 섹션 9  (0) 2023.08.22
노드 교과서 섹션 11  (0) 2023.08.18
노드 교과서 섹션 12  (0) 2023.08.17
노드 교과서 섹션 13  (0) 2023.08.09

+ Recent posts