Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Effective E2E Test In An Electron Application
Search
joe_re
April 24, 2017
Technology
850
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Effective E2E Test In An Electron Application
第36回 西日暮里.rb 「Electronではじめるアプリ開発」発売記念 LT
joe_re
April 24, 2017
More Decks by joe_re
See All by joe_re
Eyes on Claude Code
joere
0
140
Building Public API with GraphQL
joere
3
150
Traversing the GraphQL AST and Calculating Query Costs
joere
0
1.3k
Real-Time applications with GraphQL
joere
0
310
Prisma2 with Graphql
joere
3
1k
Go beyound static on Netlify
joere
1
380
Building Real-time Vue App
joere
4
4.7k
ReactNativeのAsyncStorageをNodeのReplから操作する
joere
0
360
Mock Native API in your E2E test
joere
2
1.2k
Other Decks in Technology
See All in Technology
AIは実装を速くする。では、私たちは何を今作るべきか?-立場を越えてリリースに向き合ったチーム開発の実践 / 20260801 Hiromi Nakaya and Naoki Takahashi
shift_evolve
PRO
2
110
「待ち時間」の消滅と「自我消耗」の加速:生成AI時代のエンジニアを救うメンタル・リソース管理
poropinai1966
0
390
論語・武士道・産業革命から見る かわるもの、かわらないもの
ichimichi
8
2k
Pavlokで始める電撃駆動開発
sgrsn
0
140
PLaMoを毎日の開発で使い育てていく
pfn
PRO
0
160
Master Dataグループ紹介資料
sansan33
PRO
1
4.8k
個人OSSが、机の上から世界に広がるまでの話
shinyasaita
1
190
基調講演:人とAIをつなぐIoTの今と未来 ー 「フィジカル」と「デジタル」が出会うその先へ【SORACOM Discovery 2026】
soracom
PRO
0
370
大 AI 時代におけるC# の事情 ~ぶっちゃけトークを交えながら~
nenonaninu
1
610
ここは地獄!つらい朝会を体験することで、チームとしてのより良い振る舞いに気づくワークショップ / The stand-up meeting from hell in the game industry
scrummasudar
0
520
LangfuseによるLLMOps基盤の構築と活用事例
zozotech
PRO
1
220
現場で使える AWS DevOps Agent 活用ノウハウ - Release Management 機能の検証結果を添えて / AWS DevOps Agent Release Management and Know-How
kinunori
5
830
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Code Review Best Practice
trishagee
74
20k
Rails Girls Zürich Keynote
gr2m
96
14k
Documentation Writing (for coders)
carmenintech
77
5.4k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
190
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.1k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
350
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Producing Creativity
orderedlist
PRO
348
40k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
420
Heart Work Chapter 1 - Part 1
lfama
PRO
8
36k
Transcript
Effective E2E Test In An Electron Application @joere
Who am I? twitter: @joe_re github: @joere 西日暮里.rb オーガナイザ working
in freee.K.K
最近本を書きました
今日はElectron の E2E テストの書き方について 3 つのポイントをお話します
Spectron
What is Spectron? Electron アプリケーションのE2E テストを実行するための テストツール テストコードの中でElectronAPI を叩くことができる ChromeDriver
+ WebDriverIO を通じてアプリケーションの 操作、情報取得が行える
Demo CafePitch https://github.com/joere/cafepitch Electron 製のマークダウンで書けるプレゼンツール このスライドもCafePitch で作っています
Example const app = new spectron.Application({ path: 'path/to/your/app' }); describe('application
launch', function () { this.timeout(10000); beforeEach(function () { return app.start(); }); afterEach(function () { return app.stop(); }); it('shows an initial window', function () { return app.client.getWindowCount().then(function (count) { assert.equal(count, 1); }); }); });
Strong Points Webdriver.io を通じて、任意のDOM 要素にアクセスして テストが書ける Electron のAPI をテストコードの中から透過的に呼び出す ことができる
Electron 内部のChromium をそのまま使うのでセットアップ の手間がない( 基本的にパスを指定するだけ) Travis やAppVeyor などのCI サービスをサポートしている
しかし、E2E テストは 壊れやすくメンテナンス が大変...
Effective1: Using Page Object Pattern
Why maintenance of E2E tests are difficult? E2E テストは画面変更に弱い 画面を変更すると関連するすべてのテストケースに
影響がある 画面要素へのアクセスが大量に発生するので 修正すべき箇所を把握しづらい
Page Object Pattern is... テストコードをページとシナリオに分ける アプリケーションの1 つの画面をオブジェクトと捉える (Page Object) Page
Object にはアサーションは含まず、 ページ操作を振る舞いとして記述する アサーションはシナリオに記述する (Page Object はライブラリとして利用されるイメージ) PageObject にはアサーションは含まない 他にも原則があるので、詳しくはSelenium の公式ページへ (https://github.com/SeleniumHQ/selenium/wiki/PageObjects)
Strong Points シナリオから煩雑な画面操作が取り除かれるので、 見通しが良くなる 複数のシナリオから1 つのPage Object を利用するので、 画面変更時にはPage Object
を変更するだけで良い ( 画面変更に強い) Page Object の振る舞い === 画面操作となるので、 変更箇所の把握が用意になる
Example export default class SlideEditorPage { constructor(private client: Client<void>) {}
inputText(text: string): WebdriverIO.Client<void> { return this.client.waitForExist('#editor').then(() => { this.client.setValue('#editor textarea', text); }); } getSlideHtml(): WebdriverIO.Client<string> { return this.client.waitForExist('.slide-content') .then(() => this.client.getHTML('.slide-content')) .then((html) => typeof html === 'string' ? html : html.join()); } ... }
話は変わって
皆さんE2E テスト 書いてますか
テストが失敗したとき どうしてますか
E2E テストの失敗は 原因を追うのが難しい...
そこで
Effective2: Record the state at the time of test failure
Electron + Spectron のAPI を利用して 失敗時の状態を取得して記録する 画面キャプチャ BrowserWindow.capturePage() ログ client.getRenderProcessLogs()
client.getMainProcessLogs()
Demo
Example function capturePage(app: Application, testName: string) { return app.browserWindow.capturePage().then((img) =>
{ fs.writeFileSync(`${outputDir}/capture_${testName}.png`, img); }); } function reportLog(app: Application, testName: string) { return Promise.all([ app.client.getRenderProcessLogs(), app.client.getMainProcessLogs() ]).then(([ rendererLogs, mainLogs ]) => { const logs = JSON.stringify({ renderer: rendererLogs, main: mainLogs }); fs.writeFileSync(`${outputDir}/logs_${testName}.txt`, logs, "utf8"); }); }
Effective3: Mock a native API
現在のSpectron(v3.6.2) では メニューの操作やファイルダイアログの 操作はできない https://github.com/electron/spectron/issues/21 Menu のAPI がJSON にserialize されていないので、process
間通信が必要なSpectron では操作が難しい アプリケーションの操作をChrome Driver を通じて行うのが Spectron の基本なので、これらのnative なAPI を必要とする 操作に対するサポートはまだ不十分
ところでElectron は ネイティブなAPI 呼び出しも、 JavaScript から 扱えるようにするため、 JavaScript のレイヤーで ラップしている
つまりElectron のAPI を 局所的に差し替えてしまえば テストができる
Electron のrequire オプションを利用する Electron は --require オプションで、起動直前にスクリプト を読み込ませることができる これを利用して、テスト実行時だけ1 部のElectron
のAPI を 書き換えるスクリプトを読み込む
Menu は作ってライブラリにした spectronfakemenu https://github.com/joere/spectronfakemenu Spectron から任意のラベルを持つメニューの クリックができる fakeMenu.apply(app); // apply
fake menu fakeMenu.clickMenu('Config'); // 'Config' Menu click fakeMenu.clickMenu('File', 'CloseTab'); // File->CloseTab Menu click
ダイアログはこんな感じで差し替える const { dialog } = require('electron'); function mockShowSaveDialog() {
return 'sandbox/test.md'; }; function mockShowOpenDialog() { return [ 'sandbox/test.md' ]; }; dialog.showSaveDialog = mockShowSaveDialog; dialog.showOpenDialog = mockShowOpenDialog;
Demo
E2E テストでモックを使うのは 基本的にマナー違反なので、 あくまで必要最小限にしましょう
おさらい Effective1: Using Page Object Pattern Effective2: Record the state
at the time of test failure Effective3: Mock a native API
ところでこの話は全部本 に書いてあります( 宣伝)
Thanks for your attention!