This is an English translation of my Japanese post on Qiita.
I recently created Shiba, which is a rich markdown previewer. I wrote some tests for it.
I could not find Electron app which was tested well so much and how to test Electron app seemed not to be established enough. So I wrote the test for Shiba from scratch. Tests in Shiba are put around here.
Test Electron App
I used npm to execute tests as below.
$ npm test
I wrote package.json
to make npm test
run test runner script with node.js. I created tiny Electron app for test. And the runner script runs the test Electron app.
// scripts/run-test.js 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);
run-test.js
inherits the stdio
of test Electron app because tests are executed on the app and app would exit after all test executed. The test electron app in Shiba is here.
I used mocha and chai to test JavaScript (via TypeScript).
Test Codes for Browser Process
Browser process is run on iojs, so simply running tests on browser process outputs the result to console. I wrote tests as below.
app.on('ready', function() { let mocha = new Mocha(); global.assert = chai.assert; // Add test files which are passed by process.argv mocha.ui('bdd').run(function(failures) { process.on('exit', function(){ process.exit(failures); }); app.quit(); }); });
We can't specify exit status to app.quit()
directly but hooking app exit enables to overwrite the status as above.
Test Codes for Renderer Process
I also wrote the tests for renderer process codes with mocha and chai. I refer this page to test frontend JavaScript code with mocha and chai, install mocha and chai with bower and load them from index.html
directly.
As I wrote previously, I use TypeScript. So my test code for frontend is bundled as index.js
. index.html
simply loads index.js
with <script>
tag and tests them.
In order to test frontend code, we need to open the browser window. The test Electron app opens window with BrowserWindow
object and loads index.html
by loadUrl()
. In Shiba, the code is around here. The result of tests are displayed in the window, so it is needed to call app.quit()
after the window is closed.
If you have some files to test or you need to load test files dynamically, I think passing the names of files from browser process to renderer process via ipc
or executing the test scripts using BrowserWindow.webContents().executeJavaScript()
is good way.
If browser process wants to know the result of front test executed in renderer process, it also seems to need ipc
.
Test on Travis CI
It bothered me to run Electron app on Travis CI. When I tried to run Electron app simply on Travis CI, I got below error.
Gtk: cannot open display:
Electron(Chromium) doesn't have headless mode and it seems never to be implemented.
I found that Xvfb can open a virtual display for X. I decided to use it.
Write .travis.yml
sudo: false
Although it is not related to testing Electron app, setting sudo
to false
is useful because it introduces new container-based worker.
I used addon
to install xvfb
with apt
because sudo
is not available.
addons: apt: packages: - xvfb
And then, install
phase opens the virtual display by Xvfb as below.
install: - export DISPLAY=':99.0' - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
$DISPLAY
is necessary because Electron looks $DISPLAY
on start up.
Finally, the environment to test Electron app is ready. Simply run it on script
phase.
script: - npm test
The .travis.yml
for Shiba is here.