본문 바로가기

JS Ecosystem

Mocha, chai, jsdom을 활용한 JS 테스팅(2) - Mocha 와 chai

오늘도 열정, 감사, 겸손!

 

1편에서 jsdom을 활용하여 테스트할 window.document 객체를 생성하는 부분을 알아 보았다.

2편에서는 실제적인 테스팅 도구인 Mocha와 chai를 가지고 기술을 한다.

 

테스트 자동화와 Mocha를 알고 싶다면 클릭

 

Mocha는 js 테스트 프레임워크이고 chai는 Node.js 기반의 assertion 라이브러리이다.

 

먼저 Mocha의 적용 부터 살펴 볼 예정인데, 아래의 활용 코드를 보자.

    describe("Step 1 - 숫자 버튼을 누르고 화면에 숫자를 입력하기", function () {
      it("처음 숫자 버튼을 눌렀을 때, 첫 번째 화면에 누른 숫자가 보여야 합니다.", function (done) {
        const test = ["3", "3"];
        const clicks = test.slice(0, -1);
        const expected = test.slice(-1)[0];
        const display = window.document.querySelector(".calculator-display");
        clicks.forEach(function (click) {
          const button = getButtonBy(click, allButtons);
          button.dispatchEvent(clickEvent);
        });
        expect(display.textContent).to.equal(expected);
        done();
      });

주요 함수는 describe와 it, done 이다.

 

describe(string, func()) 형식이며 string에는 테스트를 할 내용을 기술해 준다.

 

function() { } 에서 본문에는 it(string, func(done){

 ... 

 done();

}) 의 형식으로 기술하며, it() 안에는 테스트 케이스를 기술하면 된다.

 

정리를 하면

  • describe(testgroup_name): 테스트 그룹
  • it(test_name): 테스트 케이스

 

it() 함수안에 콜백 함수는 done을 인자로 받고 비동기 호출을 위해 done()함수를 코드의 마지막에 선언해주어야 한다.

done()함수로 it는 Mocha 테스트 완료하기 위해 기다려야 한다는 것을 알게 된다고 한다.

아래는 공식 문서에 나와 있는 done()의 사용에 대한 설명이다.

ASYNCHRONOUS CODE
By adding an argument (usually named done) to it() to a test callback, Mocha will know that it should wait for this function to be called to complete the test. This callback accepts both an Error instance (or subclass thereof) or a falsy value; anything else is invalid usage and throws an error (usually causing a failed test).

Mocha 공식 문서는 여기 클릭

공식 페이지에서 cmd + F 를 친 후 done 이라고 입력하면 바로 내용을 찾을 수 있다.

 

자, 여기까지가 Mocha의 내용이다.

 

다음의 한 줄은 chai 라이브러리의 내용이다.

expect(display.textContent).to.equal(expected);

chai는 assertion library인데 assertion (다른 말로 표명, 의견을 표명한다의 그 '표명')은

프로그램 개발에서 개발자가 반드시 참이어야 한다고 생각하는 사항을 표현한 논리식을 말한다.

 

chai는 몇개의 assertion을 제공하는데, BDD와 TDD 스타일로 나눈다고 한다.

그 명령어가 바로

Should, Expect, Assert 이다.

Chai에 대해 조금 더 알고 싶다면 여기 클릭

 

BDD 스타일의 Expect를 선호하는 어느 개발자님의 이야기는 여기 클릭

 

그리고 BDD 스타일의 expect는 위의 보기 코드 처럼 함수 체이닝을 이용하여 하나의 영어 문장으로 단일 테스트를 작성할 수 있어서 직관적인 느낌을 받는다고 하는데 그 의견에 조금씩 동의가 되고 있다.

 

expect(display.textContent).to.equal(expected);

위의 코드는 display.textContent와 expected가 동등(equal)하다는 것이 참인지 여부를 테스트 하는 구문인 것이다.

 

expect assertion에서 사용되는 체이닝 함수는 아래와 같다.

  • to
  • be
  • been
  • is
  • that
  • which
  • and
  • has
  • have
  • with
  • at
  • of
  • same
  • but
  • does
  • still

 

예를 들어 { value: 1 } 는 value라는 프로퍼티를 가지고 있음 테스트하고 싶으면 아래와 같이 작성하면 된다.

expect({value: 1}).to.have.own.property('value');

 

chai에 대해서 알아보는 것을 잠시 멈추고 다시 코드로 돌아가 보자. 

코드가 너무 멀리 있어 다시 가져왔다.

    describe("Step 1 - 숫자 버튼을 누르고 화면에 숫자를 입력하기", function () {
      it("처음 숫자 버튼을 눌렀을 때, 첫 번째 화면에 누른 숫자가 보여야 합니다.", function (done) {
        const test = ["3", "3"];
        const clicks = test.slice(0, -1);
        const expected = test.slice(-1)[0];
        const display = window.document.querySelector(".calculator-display");
        clicks.forEach(function (click) {
          const button = getButtonBy(click, allButtons);
          button.dispatchEvent(clickEvent);
        });
        expect(display.textContent).to.equal(expected);
        done();
      });

위의 코드를 앞의 설명을 바탕으로 자세하게 설명하겠다.

변수 display는 우리 생성한 document의 className이 calculator-display를 담고 있고 display.textContent인 것은 실제 계산기의 화면을 가리키는 것이다. 테스트 코드의 실행을 통해 계산기 화면에 표시된 텍스트 내용과 expected에 담은 배열의 0번째 요소인 "3"이 일치하는지 여부를 테스트 하는 것이다.

 

그런데 여기서 우리가 한 가지 알아야 하는 중요한 것이 있다.

바로 실제로 계산기의 버튼을 누르는 이벤트를 테스트 하면서 실행해야 한다는 것이다.

여기에 관련된 것이 바로 dispatchEvent이고 일반적으로 커스텀 이벤트 디스패치라고 한다.

 

다음 편에는 JS 를 실제로 테스트 하기 위한 이벤트를 실행하는 이벤트 디스패치에 대해 알아보도록 하자.

 

읽으며 이해하려고 노력하시느라 고생하셨습니다.