본문 바로가기

JS Ecosystem

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

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

(Testing) Mocha, chai, jsdom을 활용한 JS 테스팅(3) - custom event dispatch

 

Bare minimum 수준의 테스트 통과 사례이다.

JS테스팅에서 DOM을 생성하는 자바스크립트 파일을 테스팅할 때 이벤트를 직접 만들어서 자바스크립트 웹 애플리케이션이 제대로 작동하는 지를 점검해야 하는 경우가 있다. Mocha로 단순 JS파일을 테스트하는 작업도 낯선데 DOM을 조작하는 calculator 애플리케이션에 대해서 testing을 하는 작업에 대해 기술하도록 하겠다.

 

1. Node.js와 jsdom으로 document 객체 생성하기

if (typeof window === "undefined") {
  // for node env
  const fs = require("fs");
  const path = require("path");
  const cwd = process.cwd();
  const { JSDOM } = require("jsdom");
  const { expect } = require("chai");

  const prepared = fs.readFileSync(path.join(cwd, "/script.js"), {
    encoding: "utf-8"
  });
  const html = fs.readFileSync(path.join(cwd, "/calculator.html"));

  let window;
  window = new JSDOM(html, { runScripts: "dangerously" }).window;
  const script = window.document.createElement("script");
  script.textContent = prepared;

  window.document.body.appendChild(script);

  test(window, expect);
} else {
  // for browser env
  var expect = chai.expect;
  test(window, expect);
}

fs, path, cwd는 모두 node.js를 활용해서 script.js와 calculate.html 파일을 읽어오기 위한 값들이다.

process.cwd는 현재 node가 실행되는 디렉토리를 가리킨다.

file system 모듈에서 path.join()은 join함수 안의 인자들을 하나의 string 변환해서 파일의 경로를 표시한다.

 

위의 코드에서 prepared와 html로 각각 js파일과 html 파일을 읽어온 것을 알 수 있다.

이제 읽어온 파일은 우리가 vscode에서 해당 파일을 브라우저에 띄우는 것과 같은 작업을 해주어야 한다.

 

이러한 작업을 해주는 것이 jsdom이다.

new JSDOM 명령어를 통해 node.js 환경에서 브라우저 DOM에 접근할 수 있게 해준다.

 

이해를 돕기 위해 공식 문서에 있는 샘플 코드를 보자

const jsdom = require("jsdom");
const { JSDOM } = jsdom;

const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
console.log(dom.window.document.querySelector("p").textContent); // "Hello world"

new JSDOM() 함수안에 간단한 html 요소를 넣고 dom이라는 변수에 담았다.

이제 dom.window.document를 활용해서 해당 html 요소 <p> 태그에 텍스트를 가져올 수 있다.

 

작성한 파일을 보면

window = new JSDOM(html, { runScripts: "dangerously" }).window;

html 파일을 넣어 주었고 runScripts라는 프로퍼티를 함께 적용한 것을 볼 수 있다.

해당 내용에 대해서는 github/jsdom 을 참고하라.

간략히 이야기 하자만 runScripts 프로퍼티를 적용한 이유는

"enable executing scripts inside the page, you can use the runScripts: "dangerously" option"

웹 페이지에서 script 파일을 를 실행시키기 위함이다. (이 프로젝트에서는 script.js 파일이다.)

 

※ 참고 node로 js 데이터를 파싱해서 스크롤 할 수 있는 방법까지 있다.
http://uixkr.github.io/archives/96
※ 참고 window 객체와 document 객체의 차이에 대해서도 알아두자. 여기서 사용한 window.document와 document 객체는 동일하다.
https://developer-talk.tistory.com/125

 

코드를 좀 더 살펴보자.

const script = window.document.createElement("script");
  script.textContent = prepared;

  window.document.body.appendChild(script);

 

위의 참고자료에 있는 node로 js 파싱하는 것을 참고하면 된다.

createElement로 script 요소를 하나 만들고 script 요소에 콘텐츠에 미리 작성한 script.js 파일을 넣어 주고

window.document.body 객체애 append 해주었다.

이로써 html 파일이 생성되고 script도 실행되는 단계에 까지 이르러서 테스트를 준비할 수 있게 된 것이다.

 

여기까지는 jsdom의 도움을 받았다. 이후로는 mocha와 chai의 도움을 받아야 한다.