この記事ではElectronアプリのRendererプロセスのテスト方法について紹介します。
Electronアプリのテスト方法とTravic CIの連携については、Electron アプリを Travis CI でテストする に詳しく解説されています。この方法はBrowserプロセス・Rendererプロセス共にテストしていますが、テスト結果が、Browserプロセスのテストのみです。この記事はRendererプロセスのテストを行うステップを解説します。
今回のコードは、jprichardson/electron-mocha を参考にしています。このリポジトリは、ElectronのRendererプロセスでテストを実行できる便利ツールです。
今回はテストファイルをコード内で指定しますが、上記の記事にもあるとおり、BrowserWindow.webContents.executeJavaScript()
を使うと外部から手軽にJSをロードできるかも知れません。
概要と全体の構成
ディレクトリの構成は次のとおりです。
├── package.json
├── test
│ └── electron_test.js
└── test-runner
├── index.html
├── index.js
└── main.js
テストフレームワークにはMochaとChaiを使い、ipc経由でテスト結果をBrowserプロセスでターミナルに表示します。
test
ディレクトリには各テストコードを格納します。test-runner
ディレクトリは、テストを走らせるためのファイルです。main.js
は、BrowserWindow
を作成してElectronを表示します。BrowserWindow
に表示するHTMLはindex.html
にあり、index.js
はHTML内で<script>
タグでロードします。
今回のテストではelectron-prebuiltとmochaとchaiを使うので、あらかじめnpmからインストールしましょう。
npm install electron-prebuilt mocha chai
テストの用意
今回は、次の単純なテストを走らせます。このテストは window.document
オブジェクトを参照しているため、Rendererプロセスでのみテストがパスします。
describe('Electron renderer process', function() {
describe('document object', function() {
it('is an Document object', function() {
expect(window.document).to.be.an.instanceof(Document);
});
});
});
テストランナー
test-runner/index.html
HTMLファイルは単純に、index.js
を読み込むだけです。
<!doctype html>
<html>
<head>
<script src="./index.js"></script>
</head>
<body></body>
</html>
test-runner/index.js
index.js
はRendererプロセスで実行されます。このファイルからテストをロードして、テスト結果をipcに送信します。
var remote = require('remote');
var remoteConsole = remote.require('console');
var ipc = require("electron").ipcRenderer;
var mocha = require('mocha');
var expect = require('chai').expect;
Error.stackTraceLimit = Infinity;
console.log = function () {
remoteConsole.log.apply(remoteConsole, arguments);
};
console.warn = function () {
remoteConsole.warn.apply(remoteConsole, arguments);
};
console.dir = function () {
remoteConsole.dir.apply(remoteConsole, arguments);
};
window.onerror = function (message, filename, lineno, colno, err) {
ipc.send('mocha-error', {
message: message,
filename: filename,
err: err,
stack: err.stack
})
};
var runner = new mocha();
runner.reporter('nyan');
runner.ui('bdd');
runner.files = mocha.utils.lookupFiles('test', ['js'], true);
runner.run(function (failureCount) {
ipc.send('mocha-done', failureCount);
});
まず console.log = function() { ... }
でconsole.log
メソッドを再定義して、remote.require('console')
に流します。これでRendererプロセスのconsole出力がBrowserプロセスのconsoleへ渡されるので、テストの結果をターミナルに流すことができます。
例外発生などのエラーは、window.onerror
にイベントリスナを設定し、mocha-error
イベントをipcに渡してRendererプロセスに通知します。Mocha終了時は mocha-done
イベントをipcに渡して、FAIL数をRendererプロセスに通知します。
test-runner/main.js
Browserプロセス側の、BrowserWindowを作成するmain.js
です。
var app = require('app');
var ipc = require('electron').ipcMain;
var BrowserWindow = require('browser-window');
var path = require('path');
var util = require('util');
process.on('uncaughtException', function (err) {
console.error(err);
console.error(err.stack);
process.exit(1);
});
app.on('ready', function () {
var win = new BrowserWindow({ height: 700, width: 1200 });
win.loadURL('file://' + __dirname + '/index.html');
ipc.on('mocha-done', function (event, failureCount) {
process.exit(failureCount > 0 ? 1 : 0);
});
ipc.on('mocha-error', function (event, data) {
process.stderr.write(util.format('\nError encountered in %s: %s\n%s',
path.relative(process.cwd(), data.filename),
data.message,
data.stack));
process.exit(1);
});
});
Rendererプロセスで送信するメッセージ mocha-done
と mocha-error
を受け取ります。mocha-done
はMocha終了時に送信され、failureCount
が0より大きいと終了コード1で終了するため、CIなどではテストがFAILするようになります。
テスト実行
テスト実行は、electron
に main.js
を指定します。
./node_modules/.bin/electron test-runner/main.js
テストがPASSすると、かわいいnyancatが画面を走ります。
またテストがFAILすると、通常のMocha同様、FAILしたテストが表示されます。
Travic CIとの連携については、Electron アプリを Travis CI でテストする に詳しく解説されているので、参照してみてください。