본문 바로가기
Testing

[Jest #3] 테스트 전/후 작업

by 쾌횽 2023. 7. 20.
반응형

테스트를 작성하다보면 테스트 전/후에 작업해주어야하는 일들이 생긴다. Jest는 이런 일들을 처리할 수 있는 헬퍼함수를 제공한다.

 

// fn.js

const fn = {
	add: (num1, num2) => num1 + num2,
}

module.exports = fn;

fn파일에 add메소드를 작성하고, 테스트 페이지에서 코드를 작성해준다.

// fn.test.js

const fn = require("./fn");

let num = 0;

test("0 더하기 1은 1이야.", () => {
  num = fn.add(num, 1);
  expect(num).toBe(1);
});

// passed

num변수를 만들고 1을 더하는 테스트 코드를 작성해서 돌렸더니 잘 통과되었다.

더 많은 테스트를 하기 코드를 작성하였다.

// fn.test.js

const fn = require("./fn");

let num = 0;

test("0 더하기 1은 1이야.", () => {
  num = fn.add(num, 1);
  expect(num).toBe(1);
});

test("0 더하기 2은 2이야.", () => {
  num = fn.add(num, 2);
  expect(num).toBe(2);
});

test("0 더하기 3은 3이야.", () => {
  num = fn.add(num, 3);
  expect(num).toBe(3);
});

test("0 더하기 4은 4이야.", () => {
  num = fn.add(num, 4);
  expect(num).toBe(4);
});

테스트 결과는,

 FAIL  ./fn.test.js
  ✓ 0 더하기 1은 1이야. (3 ms)
  ✕ 0 더하기 2은 2이야. (3 ms)
  ✕ 0 더하기 3은 3이야. (1 ms)
  ✕ 0 더하기 4은 4이야. (1 ms)

Test Suites: 1 failed, 1 total
Tests:       3 failed, 1 passed, 4 total
Snapshots:   0 total
Time:        0.596 s, estimated 1 s

당연하게도 실패하게 된다. num에 게속 새로운 값이 할당되기때문이다. 

이러한 코드를 통과시키려면 각 테스트를 실행하기 직전에 num을 다시 초기화해주는 작업이 필요하다.

이럴때 사용할 수 있는 것이 beforeEach()이다.

// fn.test.js

const fn = require("./fn");

let num = 0;

beforeEach(() => {
  num = 0;
});

test("0 더하기 1은 1이야.", () => {
  num = fn.add(num, 1);
  expect(num).toBe(1);
});

test("0 더하기 2은 2이야.", () => {
  num = fn.add(num, 2);
  expect(num).toBe(2);
});

test("0 더하기 3은 3이야.", () => {
  num = fn.add(num, 3);
  expect(num).toBe(3);
});

test("0 더하기 4은 4이야.", () => {
  num = fn.add(num, 4);
  expect(num).toBe(4);
});

// passed

beforeEach()를 통해서 테스트 이전에 num을 0으로 초기화하고있다. 

비슷하게 afterEach()를 사용하면 테스트 이후에 num을 0으로 초고화한다.

 

만약, 전 / 후 작업이 시간이 걸리는 작업이라면 어떻게 될까?

DB에서 유저 정보를 가져오고 가져온 후에는 DB연결을 끊어야하는 작업을 진행해보자.

// fn.js

const fn = {
    add: (num1, num2) => num1 + num2,
    connectUserDB: () => {
    return new Promise((res) => {
      setTimeout(() => {
        res({
          name: "Mike",
          age: 30,
          gender: "male",
        });
      }, 500);
    });
  },
  disconnectDB: () => {
    return new Promise((res) => {
      setTimeout(() => {
        res();
      }, 500);
    });
  },
}

module.exports = fn;

connectUserDB는 0.5초후에 유저정보를 가져오고, disconnectDB는 연결을 끝내는 코드를 작성했다.

test.js에서 테스트 코드를 작성해준다.

// fn.test.js

const fn = require("./fn");

let user;

beforeEach(async () => {
  user = await fn.connectUserDB();
});

afterEach(() => {
  return fn.disconnectDB();
});

test("이름은 Mike", () => {
  expect(user.name).toBe("Mike");
});

// passed

결과는 통과이다.

정보를 가져오고 연결을 끊는데까지 1초의 시간이 걸렸다.

더 많은 테스트를 하기위해 아래의 코드를 추가해 준다.

test("나이는 30", () => {
  expect(user.age).toBe(30);
});

test("성별은 남성", () => {
  expect(user.gender).toBe("male");
});

결과는 통과이고, 시간은 3.541초, 약 4초가 걸렸다. 그런데 이러한 테스트 과정이 더 많아지면 시간도 많이 소요될 뿐만아니라 DB의 접속이 너무 많아 지게 된다. DB에 접속해서 모든 테스트를 마친 후에 연결을 끊는게 더 효율적이다. 이때 사용할 수 있는  함수는 beforeAll(), afterAll() 이다.

// fn.test.js

const fn = require("./fn");

let user;

beforeAll(async () => {
  user = await fn.connectUserDB();
});
afterAll(() => {
  return fn.disconnectDB();
});

test("이름은 Mike", () => {
  expect(user.name).toBe("Mike");
});
test("나이는 30", () => {
  expect(user.age).toBe(30);
});
test("성별은 남성", () => {
  expect(user.gender).toBe("male");
});

작업 시간은 1.492 s 약, 2초가 걸렸다. 이전의 작업보다 시간이 단축된 것을 볼 수 있다.

 

다른 유용한 함수가 있는데 ,

여러 테스트중 하나의 테스트코드만 동작하고 싶을 때는 test.only()를 사용하여 작성해 주고, 하나의 테스트 코드를 스킵하는 test.skip()이 있다.

반응형

댓글