본문 바로가기
Testing

[Jest #1] Jest로 기본적인 테스트 작성법

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

Jest ?

jset는 페이스북에서 만들어서 React, Vue와 같은 Javascript개발자들에게 많이 활용되고 있는 테스팅 프레임워크이다.

jest는 zero config의 철학을 가지고 있어서 별도의 설치 없이 빠르게 테스트 코드를 작성헐 수 있는 장점이 있다.

또한, 문서화가 잘 형성되 있으며 결과를 신속하게 제공하는 접근하기 쉽고 친숙하며 기능이 풍부한 API로 테스트를 작성할 수 있다.

프로젝트 생성

$mkdir jest-test
npm init -y
npm i -D jest

jest-test라는 이름의 새로운 폴더를 만들고 npm을 연결해준다.

jest를 개발 의존성으로 설치해 준다.

test 스크립트 수정

 "scripts": {
    "test": "jest"
  },

package.json파일에 test스크립트를 jest로 수정해준다.

이렇게 설정해주면 터미널에서 npm test를 입력하면 jest커맨드를 실행 할 수 있다.

 

코드작성

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

module.exports = fn;

fn.test.js라는 파일을 만들어준다. npm test를 실행하면 프로젝트내의 모든 test파일 혹은 __tests__ 찾아서 실행한다.

만약 특정 파일만 테스트 하고 싶다면 npm test뒤에 파일명을 입력하면 된다.

// fn.js

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

module.exports = fn;

fn파일에 add라는 매소드를 만들고 num1과 num2를 인자로 받아 더해주는 객체를 만들어 준다.

// fn.test.js

const fn = require("./fn")

test("1은 1이야", ()=> {
	expect(1).toBe(1);
})

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

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

npm test !

> jest_tutorial@1.0.0 test
> jest

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

  ● 3더하기 3은 5야

    expect(received).toBe(expected) // Object.is equality

    Expected: 5
    Received: 6

      10 |
      11 | test("3더하기 3은 5야", () => {
    > 12 |   expect(fn.add(3, 3)).toBe(5);
         |                        ^
      13 | });
      
Test Suites: 1 failed, 1 total
Tests:       1 failed, 2 passed, 3 total
Snapshots:   0 total
Time:        0.56 s, estimated 1 s
Ran all test suites.

첫번째와 두번째는 무사 통과 했고 세번째는 실패를 했다. 그 결과 값이 터미널에 보여지게 된다.

기본적인 구조는 아래와 같다.

test("테스트 설명", () => {
	expect("검증 대상").toBe("기댓값")
});

기대값부분의 사용되는 함수를 Matcher라고 한다. 위에서 사용된 toBe()함수는 숫자나 문자와 같은 객체가 아닌 기본값(preimitive)값을 비교할 때 사용한다.

 

유용한 Matchers

toEqual()

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

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

test("3더하기 3은 5야", () => {
  expect(fn.add(2, 3)).toEqual(5);
});

테스트는 둘 다 통과했다.

하지만 객체를 기대값으로 테스트하기 위해서는 toEqual()를 사용해야 유용하다.

// fn.js

const fn = {
	add: (num1, num2) => num1 + num2,
    makeUser: (name, age) => ({ name, age}),
};

module.exports = fn;

이름과 나이를 입력받아서 객체를 리턴해준다.

// fn.test.js

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

test("이름과 나이를 전달받아서 객체를 반환해줘", () => {
  expect(fn.makeUser("Mike", 30)).toBe({
    name: "Mike",
    age: 30,
  });
});

toBe()를 사용하면 테스트는 실패하게 된다.

jest_tutorial@1.0.0 test
> jest

 FAIL  ./fn.test.js
  ✕ 이름과 나이를 전달받아서 객체를 반환해줘 (7 ms)

  ● 이름과 나이를 전달받아서 객체를 반환해줘

    expect(received).toBe(expected) // Object.is equality

    If it should pass with deep equality, replace "toBe" with "toStrictEqual"

    Expected: {"age": 30, "name": "Mike"}
    Received: serializes to the same string

      2 |
      3 | test("이름과 나이를 전달받아서 객체를 반환해줘", () => {
    > 4 |   expect(fn.makeUser("Mike", 30)).toBe({
        |                                   ^
      5 |     name: "Mike",
      6 |     age: 30,
      7 |   });

      at Object.toBe (fn.test.js:4:35)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.542 s, estimated 1 s

객체나 배열은 재귀적으로 돌면서 값을 확인하기 때문에 toEqual()을 사용해야한다.

jest의 특징은 Matcher를 올바르게 사용할 수 있도록 toEqual()함수를 사용하라고 가이드해준다.

그럼 toBe()대신 toEqual()을 사용해보자.

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

test("이름과 나이를 전달받아서 객체를 반환해줘", () => {
  expect(fn.makeUser("Mike", 30)).toEqual({
    name: "Mike",
    age: 30,
  });
});

결과는 통과이다. 

위 에러 메세지에

If it should pass with deep equality, replace "toBe" with "toStrictEqual" 라는 문구가 나오는데 toStrictEqual()는 toEqual()보다 엄격하게  검사를 해준다.

// fn.js

const fn = {
	add: (num1, num2) => num1 + num2,
    makeUser: (name, age) => ({ name, age, gender: undefined}),
};

module.exports = fn;

 makeUser에 gender를 추가해주고 테스트를 진행하면,

//fn.test.js

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

test("이름과 나이를 전달받아서 객체를 반환해줘", () => {
  expect(fn.makeUser("Mike", 30)).toEqual({
    name: "Mike",
    age: 30,
  });
});   //fail

test("이름과 나이를 전달받아서 객체를 반환해줘", () => {
  expect(fn.makeUser("Mike", 30)).toStrictEqual({
    name: "Mike",
    age: 30,
  });
});   //passed

toStrictEqual()만 테스팅에 통과한것을 볼 수 있다.

 

toBeNull(), toBeUndefined(), toBeDefined()

null,undefined.defined값이면 통과한다.

 

toBeTruthy()

toBeFalsy()

불리언값을 선별해준다.

// fn.test.js

test("0은 false입니다.", () => {
  expect(fn.add(1, -1)).toBeFalsy();
});  //passed

test("값은 true입니다.", () => {
  expect(fn.add("hello", "world")).toBeTruthy();
});  //passed

 

 

toBeGreaterThan() 크다

toBeGreaterThanOrEqual() 크거나 같다

toBeLessThan() 작다

toBeLessThanOrEqual() 작거나 같다

 

toMatch()

문자열에 포함되있는지 확인한다. 정규표현식을 이용할 수 있다.

// fn.test.js

//문자열에 요소 찾기
test("Hello World에 a라는 글자가 있나?", () => {
  expect("Hello World").toMatch(/h/i);
}); // passed

toContain()

배열에서 특정 요소가 있는지 확인한다.

test("유저 리스트에 Mike가 있나?", () => {
  const user = "Kai";
  const UserList = ["Tom", "Jane", "Kai"];
  expect(UserList).toContain(user);
}); // passed

toThrow()

예외 발생 여부를 테스트해야하는 경우 toThrow()를 사용한다. 

먼저 fn.js파일에 예와를 발생시키는 함수를 작성한다.

// fn.js

const fn = {
	add: (num1, num2) => num1 + num2,
    makeUser: (name, age) => ({ name, age, gender: undefined}),
    throwErr: () => {
    	throw new Error("xx");
  	},
};

module.exports = fn;
// fn.test.js

test("이거 에러 나나요?", () => {
  expect(() => fn.throwErr()).toThrow("xx");
}); // passed

expect함수 내부에서 fn.throwErr()이라는 에러를 발생시켰고, "xx"라는 특정 에러에대해 테스트를 진행하였을때 통과가 나올 수 있었다.

끝으로

Jset에대한 정말 기본적인 테스트 코드를 진행해 보았다. 자바스크립트를 사용하는데 있어서 비동기 코드를 테스트 해야할 일이 많은데 Jest로 비동기를 다룰 수 있도록 공부해 봐야겠다.

 

 


참고 자료

반응형

댓글