最近 Shiba という markdown プレビューアプリをつくったのですが,テストが無かったので追加してみました.
Electron と Polymer と TypeScript でリッチなマークダウンプレビュアー Shiba つくった
Electron アプリでテストを書いてるものは探した限りではあまりなくて,やり方もどこにも無かったので,今回は完全に我流でやってみました.Travis CI で CI するところまで含めて,そのメモ書き.実際に Shiba でテストを扱っているのは この辺り です.
Electron アプリのテスト
npm を使って下記のようにテストを実行できるようにします.
$ npm test
npm test
は node で JS のコードを実行するように package.json
で設定し,そのスクリプトの中でテスト用の小さな Electron アプリを実行するようにします.
var electron = require('electron-prebuilt');
// ...
var finished = child_process.spawnSync(
electron,
['path/to/test-app', 'test-file1.js', 'test-file2.js'],
{stdio: 'inherit'}
);
process.exit(finished.status);
テストは Electron アプリ上で実行するため,Electron アプリの stdio
を引き継ぐようにします.実行する Electron アプリはエントリポイントとなっている JS のソース内でテストスクリプトを実行し,結果を出力して終了します.実際に書いたテスト用 Electron アプリは こんな感じ です.
今回は mocha と chai でテストを書いてみました.
ブラウザプロセスのコードのテスト
ブラウザプロセスは iojs で実行されるので,下記のように,アプリの準備ができたらテストファイルをセットして実行すればコンソールに出力が出ます.
app.on('ready', function() {
let mocha = new Mocha();
global.assert = chai.assert;
// 引数で渡ってきたテストファイルを追加
mocha.ui('bdd').run(function(failures) {
process.on('exit', function(){ process.exit(failures); });
app.quit();
});
});
app.quit()
時の終了ステータスを直接指定する方法はありませんが,上記のようにしてステータスを指定できます.
レンダラプロセスのコードのテスト
mocha と chai を使ってフロントエンドのテストコードを書きます.ここに載っている方法 で,bower を使ってインストールし,index.html
からそれを参照します.
僕はテストを TypeScript で書いていて,レンダラプロセスのテストコードが1つのファイルになっているので,単純に index.html
でそれを <script>
タグで読み込んでテストを実行します.
テストを実行するためのウィンドウはテスト用の Electron アプリの中で BrowserWindow
オブジェクトをつくって loadUrl()
で読み込みます(実際にやっている箇所はここ).結果はウィンドウ内の <div id="mocha"></div>
に表示されます.ここでは,ウィンドウが閉じた時に app.quit()
が呼ばれるようにしておきます.
ファイルが複数あったり,動的に読み込むファイルを変えたい場合はブラウザプロセスから ipc 経由で渡して動的に <script>
で読み込むか,BrowserWindow.webContents().executeJavaScript()
で読み込ませるのが良さそうです.
また,テストの結果をブラウザプロセス側に返したければ,その場合も ipc 越しに渡す必要がありそうです.
Travis CI でのテスト
Electron アプリを Travis で動かすのは少し面倒でした.単純に Travis 上で Electron アプリを実行しようとすると次のようなエラーログが出てしまいます 1.
Gtk: cannot open display:
Electron(というか Chromium)はヘッドレスモードのようなディスプレイを開かないモードが無く,今後も実装しないようなので,ここをどうにかしないといけません.
一般的にブラウザのテストをディスプレイを開けないような環境でどうやっているのかを調べてみると Xvfb を使って仮想的にディスプレイを開くことで解決しているようです.今回はそれを使います.
.travis.yml
を書く
sudo: false
直接は関係ないですが,sudo
を false
にしておくと新しいコンテナベースのワーカ を使うことができ,CI の立ち上がりが速くなります.
sudo
が使えなくなるので,apt
によるインストールは addon
を使います.ここでは Xvfb をインストールします.
addons:
apt:
packages:
- xvfb
次に,install
フェーズで Xvfb を立ち上げて仮想ディスプレイをつくっておきます.
install:
- export DISPLAY=':99.0'
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
Electron は $DISPLAY
を見ているようで,$DISPLAY
を設定しておかないと動きません.画面サイズは都合の良いものに適宜調整すると良さそうです.これで,あとは最初に書いておいたテストスクリプトを実行すると無事 Electron が動き,その上でテストスクリプトが走ります.
script:
- npm test
今回書いた .travis.yml
はこんな感じです.
また,Travis CI 上でのテストログはこんな感じ になりました.めでたし.