Help us understand the problem. What is going on with this article?

ElectronのRendererプロセスのテスト

More than 3 years have passed since last update.

この記事では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プロセスでのみテストがパスします。

test/electron_test.js
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 を読み込むだけです。

test-runner/index.html
<!doctype html>
<html>
  <head>
    <script src="./index.js"></script>
  </head>
  <body></body>
</html>

test-runner/index.js

index.js はRendererプロセスで実行されます。このファイルからテストをロードして、テスト結果をipcに送信します。

test-runner/index.js
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です。

test-runner/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-donemocha-error を受け取ります。mocha-done はMocha終了時に送信され、failureCount が0より大きいと終了コード1で終了するため、CIなどではテストがFAILするようになります。

テスト実行

テスト実行は、electronmain.js を指定します。

./node_modules/.bin/electron test-runner/main.js

テストがPASSすると、かわいいnyancatが画面を走ります。

success.png

またテストがFAILすると、通常のMocha同様、FAILしたテストが表示されます。

fail.png

Travic CIとの連携については、Electron アプリを Travis CI でテストする に詳しく解説されているので、参照してみてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした