A. 테스트 자동화 실습
Javascript를 테스트할 수 있는 도구로 Jest가 있습니다. 기존 모듈들을 Jest를 통해 테스트를 진행해보겠습니다.
1. 유닛(단위) 테스트 실습
아래에 계산기 프로그램 코드가 있습니다.
add 는 두 숫자를 받아서 더하는 함수, subtract 는 두 숫자를 받아서 빼는 함수, multiple 은 두 숫자를 받아서 곱하는 함수, divide 는 두 숫자를 받아서 나누는 함수 입니다.
calculate.js
unit 단위 테스트 코드
현재 함수 단위로 나누어져 있음
// calculate.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
function multiple(a, b) {
return a * b;
}
function divide(a, b) {
return a / b;
}
module.exports = { add, subtract, multiple, divide }
'단위 테스트' 작성
calculate.test.js 파일
// calculate.test.js
const { add, subtract, multiple, divide } = require('./calculate');
describe('calculate unit test', () => {
describe("add", () => {
test("add(1,2)는 3이 되어야합니다.", () => {
expect(add(1, 2)).toBe(3);
});
});
describe("subtract", () => {
test("subtract(2,1)는 1이 되어야합니다.", () => {
expect(subtract(2, 1)).toBe(1);
});
});
describe("multiple", () => {
test("multiple(3, 4)는 12가 되어야합니다.", () => {
expect(multiple(3, 4)).toBe(12);
});
});
describe("divide", () => {
test("divide(10, 2)는 5가 되어야합니다.", () => {
expect(divide(10, 2)).toBe(5);
});
});
});
[분석을 위한 코드 재작성]
const { add, subtract, multiple, divide } = require('./calculate');
describe('calculate unit test', () => {
describe("add", () => {
test("add(1,2)는 3이 되어야합니다.", () => {
expect(add(1, 2)).toBe(3);
});
});
describe("subtract", () => {
test("subtract(2,1)는 1이 되어야합니다.", () => {
expect(subtract(2, 1)).toBe(1);
});
});
describe("multiple", () => {
test("multiple(3, 4)는 12가 되어야합니다.", () => {
expect(multiple(3, 4)).toBe(12);
});
});
describe("divide", () => {
test("divide(10, 2)는 5가 되어야합니다.", () => {
expect(divide(10, 2)).toBe(5);
});
});
});
단위 테스트 코드 분석:
describe 부분과 test 부분으로 나뉨
describe와 test 부분 둘 다
(description, callback) 형태를 가지며
- description 에는 해당 부분에 대한 카테고리 및 설명이 들어갑니다.
- callback 내부에는 다시 describe 및 test 를 선언할 수 있습니다.
test callback 내에서 기능 단위들(함수, 클래스 등)을 호출할 수 있으며
expect를 통해 값을 비교하여 정상적으로 수행했는지 확인 가능합니다.
💡 하나의 테스트에 여러 개의 expect가 들어갈 수 있습니다!
테스트 코드를 실행
여기서는 jest를 사용할 것이기 때문에 jest를 프로젝트 디렉토리 내에 설치합니다.
1) jest 설치
2) jest 명령어를 통해 테스트를 수행
$ npm i -D jest
$ npx jest # npx 명령어를 수행하면 프로젝트 내에 설치된 jest가 실행됩니다.
jest 프로그램이 *.test.js 나 *.spec.js 같은 테스트 코드 파일들을 찾아 자동으로 실행합니다.
아래는 실행 결과입니다.
- describe 이용: 해당 테스트가 무엇에 관한 테스트인지 캡션 달기가 가능
- describe 안에 describe가 들어가면 : 대분류 중분류 개념으로 내려간다
2. 통합 테스트 실습
더하기 결과와 빼기 결과를 곱하는 과정을 통해
테스트를 통합
calculate.test.js
통합 테스트 코드
// calculate.test.js
const { add, subtract, multiple, divide } = require('./calculate');
...기존 unit test
/// 통합 테스트 추가
describe("calculate integration test", () => {
test("add(1, 3)과 subtract(4, 2)를 multiple한 결과는 8입니다.", () => {
const addResult = add(1, 3);
expect(addResult).toBe(4);
const subtractResult = subtract(4, 2);
expect(subtractResult).toBe(2);
expect(multiple(addResult, subtractResult)).toBe(8);
});
});
- divide를 제외하고 add, subtract, multiple 함수들을 모아서 통합 테스트를 구성
- 개별 단위 코드들을 모아서 테스트를 구성 -> 상향식 통합 테스트
(* 하향식 통합 테스트= 하향식으로 조립된 모듈 있을 때)
B. '테스트 커버리지 확인'하는 방법
[테스트 실행]
jest 에서는 --coverage라는 옵션 사용
npx jest --coverage
[실행 결과]
모든 구문과 분기점들을 100% 커버하는 점 확인
[여기서 add 함수에 코드를 추가]
function add(a, b) {
/// 추가된 부분
if (b < 0) {
throw new Error("b가 0보다 작습니다. subtract를 사용하세요!");
}
/// ---------
return a + b;
}
b 가 0보다 작을 때, 해당 함수의 기능을 종료하고 싶으면 실질적으로 subtract 를 사용
[테스트 실행]
이 후, 다시 jest 명령어
npx jest --coverage
[실행 결과]
- Funcs를 제외한 3가지의 커버리지가 낮아졌습니다.
- 오른쪽 Uncovered Line 을 표시하여 어떤 라인이 커버 되지 않는지 알려주고 있습니다.
[그럼 이제, 테스트를 추가하여 커버리지를 다시 높여보도록]
describe("add", () => {
test("add(1, 2)는 3이 되어야합니다.", () => {
expect(add(1, 2)).toBe(3);
});
// 아래 테스트 추가
test("add(1, -1)은 에러를 던집니다.", () => {
try {
add(1, -1);
} catch (err) {
expect(err).toBeInstanceOf(Error)
expect(err).toHaveProperty("message", "b가 0보다 작습니다. subtract를 사용하세요!");
}
});
});
[테스트 실행]
npx jest --coverage
[실행 결과]
- add 테스트를 추가하여 커버리지를 다시 높였습니다.
- 추가한 테스트는 throw 부분을 실행하게 만들었으므로 해당 코드가 테스트되게 만들었습니다.
- 커버리지는 테스트 입력을 추가하여 높일 수 있는 점 기억하시길 바라겠습니다.
💡 jest는 기본적으로 *.test.js, *.spec.js 파일들만 테스트하며 커버리지 산정은 테스트 파일내에서 import 된 코드만 이용해서 계산
E2E 테스트
계산기 프로그램을 외부에 노출 시켜 누구나 사용가능하게 만들고 싶을 때, 우리는 서버 모듈을 사용합니다.
서버 모듈의 대표적인 프레임워크로 express가 있습니다.
계산기 함수를
Express 프레임워크에 옮겨줍니다.
// app.js
const express = require("express"); // express 모듈은 npm i express로 설치
const { add, subtract, multiple } = require("./calculate");
const app = express();
// 쿼리 스트링으로 받는 a와 b를 숫자로 바꾸어서 다음 컨트롤러로 넘기는 미들웨어 입니다.
app.use((req, res, next) => {
const { a, b } = req.query;
req.num = {
a: Number(a),
b: Number(b),
};
next();
});
app.get("/add", (req, res) => {
const { a, b } = req.num;
const result = add(a, b);
res.json({ result });
});
app.get("/subtract", (req, res) => {
const { a, b } = req.num;
const result = subtract(a, b);
res.json({ result });
});
app.get("/multiple", (req, res) => {
const { a, b } = req.num;
const result = multiple(a, b);
res.json({ result });
});
app.get("/divide", (req, res) => {
const { a, b } = req.num;
const result = divide(a, b);
res.json({ result });
});
module.exports = app;
그런 다음 server.js 와 server.spec.js(혹은 server.test.js)를 만들어
아래의 코드를 붙여넣습니다.
설치하지 않은 모듈이 있으면 설치 후에 진행해주세요! (설치할 모듈은 아래 코드 주석에 있습니다!)
// server.js
const http = require("http"); // http 모듈은 node에 내장되어있으므로 설치 x
const app = require("./app");
http.createServer(app).listen(10010);
---
// server.spec.js
const http = require("http");
const fetch = require("node-fetch-commonjs"); // npm i node-fetch-commonjs
const app = require("./app");
describe("E2E Test", () => {
let server;
beforeEach(() => {
// 테스트 케이스들이 독립된 환경에서 테스트할 수 있게 개별적으로 listen합니다.
server = http.createServer(app).listen(10010);
});
afterEach(() => {
// 각 테스트가 끝난후 서버를 종료시킵니다.
server.close();
// 가비지 컬렉터에서 http server 객체를 메모리에서 해제하게 만듭니다.
server = null;
});
test("사용자가 a에 3, b에 4를 담아 add로 get 요청합니다.", async () => {
const resBody = await fetch("<http://localhost:10010/add?a=3&b=4>").then(
(res) => res.json()
);
expect(resBody.result).toBe(7);
});
test("사용자가 a에 6, b에 2를 담아 subtract로 get 요청합니다.", async () => {
const resBody = await fetch("<http://localhost:10010/subtract?a=6&b=2>").then(
(res) => res.json()
);
expect(resBody.result).toBe(4);
});
});
[테스트 실행]
npx jest를 실행하여 테스트 결과를 확인
[E2E 테스트란]
실제 환경과 동일하게 구성하여
사용자가 요청하는 것부터 시작하여 결과를 받는 것
모두 테스트하는 방법론이
나머지 multiply와 divide는 개인별로 추가해보시면 되겠습니다.
'Wecode - Project 3 (부트캠프) > 세션' 카테고리의 다른 글
Software Testing 1) - [Software Test란 ? (0) | 2023.10.27 |
---|---|
이후 해보면 좋을 [계산기 프로그램 리팩토링] 과제 ** (0) | 2023.10.27 |
주니어 개발자 마인드셋 (0) | 2023.10.27 |
Docker를 활용한 AWS 실습 [개념] (0) | 2023.10.26 |
docker 세션 [개념, 명령어, docker file ] (0) | 2023.10.26 |