LoginSignup
9
8

More than 5 years have passed since last update.

ElectronでDOM依存のRendererプロセスをユニットテストする方法

Last updated at Posted at 2016-09-24

ElectronをTDDで始める際、SpectronでE2Eテストができるのはすぐに分かったのですが、Rendererプロセスのjsをユニットテストする方法がなかなか分からず苦戦したので、ここに記しておきます。
結果として、electron-mocha を使用するとシンプルにできました。

アプリの概要と構成

今回製作したアプリは、デスクトップをスクリーンキャプチャしてローカルに画像を保存するような内容になっています。
ディレクトリの構成は下記になります。

├── package.json
├── main.js
│
├── index.html
├── app.js
├── capturer.js
│
├── test
    └── test.js

main.jsindex.htmlをロードし、HTML内のapp.js経由でキャプチャと画像保存を行うモジュールcapturer.jsが呼ばれる流れになります。

テスト対象

今回のユニットテストで確認したいモジュールは、capturer.jsです。

capturer.js
const fs = require('fs');

class Capturer {
  constructor(savePath) {
    this.savePath = savePath;
  }

  capture(video, x, y, w, h) {
    const canvas = document.createElement('canvas');
    canvas.width = w;
    canvas.height = h;
    const ctx = canvas.getContext('2d');

    // 指定した矩形領域で切り抜き
    ctx.drawImage(video, x, y, w, h, 0, 0, w, h);

    // 画像のヘッダ情報を除去してデータだけにする
    const base64Img = canvas.toDataURL().replace(/^.*,/, '');

    const dstPath = this.savePath + 'test.png';

    return new Promise((resolve) => {
      fs.writeFile(dstPath, base64Img, 'base64', (err) => {
        if (err) throw err;

        resolve(dstPath);
      });
    });
  }
}

module.exports = Capturer;

スクリーンキャプチャを映すvideo要素を引数に受け取り、canvas要素に描画した上でファイルへ書き出しています。

立ちはだかる壁、そして対策

ご覧のようにDOMと密に結合している為、単純にmochaを使用するだけではテストできません。

そこで登場するのが electron-mocha です。
これはmochaをラップしたモジュールになっており、Rendererプロセスでテストを実行する機能があります。
まずはさくっとインストールしましょう。

npm install electron-mocha --save-dev

テストする!

そして、下記がテストコードになります。
test/test.jscapturer.jsだけで完結したテストになりました。

test/test.js
'use strict';

const assert = require('power-assert');
const del = require('del');
const Capturer = require('../capturer');

describe('Capturer', function() {
  const tmpImagesPath = `${__dirname}/images/`;

  let video;
  let capturer;

  beforeEach(() => {
    video = document.createElement('video');
    capturer = new Capturer(tmpImagesPath);
  });

  afterEach(() => {
    return del([tmpImagesPath]);
  });

  it('矩形領域をキャプチャして保存', () => {
    return capturer.capture(video, 0, 0, 100, 100).then((dstPath) => {
      assert(dstPath === `${tmpImgagesPath}test.png`);
    });
  }
}
package.json
{
  ~
  "scripts": {
    "test": "./node_modules/.bin/electron-mocha --renderer --require intelli-espower-loader"
  },
  "devDependencies": {
    "del": "^2.2.2",
    "electron-mocha": "^3.1.0",
    "intelli-espower-loader": "^1.0.1",
    "power-assert": "^1.4.1"
  }
}

テストの結果

特筆すべき点は下記になります。

  • package.jsonのテストコマンドに--rendererオプションを付与することで、Rendererプロセスでテストが実行される
  • test/test.js内でdocumentへアクセスできるので、スタブとしてvideo要素を生成
  • capturer.jsも同様にdocumentが活きているのでcanvas要素を生成可能
  • Spectronのようにアプリ起動に時間が掛からないので、テストの実行が速い
9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8