ElectronをTDDで始める際、SpectronでE2Eテストができるのはすぐに分かったのですが、Rendererプロセスのjsをユニットテストする方法がなかなか分からず苦戦したので、ここに記しておきます。
結果として、electron-mocha を使用するとシンプルにできました。
アプリの概要と構成
今回製作したアプリは、デスクトップをスクリーンキャプチャしてローカルに画像を保存するような内容になっています。
ディレクトリの構成は下記になります。
├── package.json
├── main.js
│
├── index.html
├── app.js
├── capturer.js
│
├── test
└── test.js
main.js
でindex.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.js
とcapturer.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のようにアプリ起動に時間が掛からないので、テストの実行が速い