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
リーダブルなE2Eテストコードのための3つのC
Search
tsuemura
August 08, 2024
7
1k
リーダブルなE2Eテストコードのための3つのC
Playwright本出版記念!Node学園 43時限目 2024-08-08
https://nodejs.connpass.com/event/325813/
tsuemura
August 08, 2024
Tweet
Share
More Decks by tsuemura
See All by tsuemura
テスト自動化ことはじめ(202412_オープンロジ版) / Enter the testing automation (2024 Dec, for OPENLOGI)
tsuemura
0
45
E2Eテストのシナリオと抽象化の粒度の話.pdf
tsuemura
6
580
テスト自動化ことはじめ
tsuemura
3
300
ようこそ、ソフトウェアテストの世界へ!
tsuemura
1
68
コンテキストとセマンティクスを意識してリーダブルなE2Eテストコードを書こう
tsuemura
12
28k
60分で学ぶE2Eテスト(実装編)
tsuemura
0
390
全部乗せフレームワーク CodeceptJS でE2Eテストを楽にしよう
tsuemura
7
5.3k
10年前に初めてVBAで業務自動化したときの思い出
tsuemura
1
14k
テストを自動化するのをやめ、自動テストを作ろう
tsuemura
72
35k
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.4k
Building an army of robots
kneath
302
44k
It's Worth the Effort
3n
183
28k
The Invisible Side of Design
smashingmag
299
50k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
KATA
mclloyd
29
14k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.3k
Mobile First: as difficult as doing things right
swwweet
222
9k
We Have a Design System, Now What?
morganepeng
51
7.3k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.9k
Practical Orchestrator
shlominoach
186
10k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
Transcript
リーダブルな E2Eテストコードのための 3つの C Takuya Suemura 2024-08-08 Playwright本出版記念! Node学園 43時限目
1
自己紹介 末村 拓也 プロフィール写真を 37年間更新し忘れている Quality Evangelist at Autify エンジニアですが、マーケティングチームに異
動しました(今日) テトリスとキーボードが好きです 2
宣伝だ テスト自動化実践ガイド CodeceptJS + Playwright の組み合わせ で E2Eテストを書く テスト自動化を始める前から運用まで広 くカバー
ハンズオンのためにゴミみたいなアプリ を頑張って作りました ゴミみたいなアプリに自動テストを 書かないといけない場合に便利 3
CodeceptJS って何 WebDriverや Playwright などをラップして単一の APIを提供する 一人称の I から始まる 自然な英文法のシンタッ
クス I click something I see something 4
その他執筆・登壇 ORDER BY LIKES 我が名は神龍 ……どんなテストもひとつだけ自動化してやろう (Qiita, 2018) クロスブラウザテストの闇と闇と闇 (D-CUBE,
2019) テストを自動化するのをやめ、自動テストを作ろう (July Tech Festa, 2020) etc 5
今日話すこと E2Eテストの認知負荷の話 認知負荷を下げる 3つの C Context Capability Component これらを CodeceptJSや
Playwrightでどう表現するか 説明は CodeceptJSでやりますが Playwrightでもできます(たぶん) 書籍ではハンズオンパートの最後に説明があります 3つの Cという言葉は出版後に思いついたので今回が初出です 6
認知負荷 (Cognitive Load) とは コードリーディングを妨げる「覚えておかないといけない」 「想像しないといけない」こと クソデカスコープ変数 クソデカ依存関数 何の意味があるのか分からない処理 7
E2Eテストの認知負荷 どこのページにいるのか、どのユーザーでログインしているのか いまやっているのはテストなのか準備なのか 何を操作しようとしているのか E2Eテストは何も考えずに書くとゴリゴリの手続き型プログラミングになるので こういうところをケアしながら書いてあげたい 8
認知負荷を下げる工夫 「あるページにいる」 「あるユーザーでログインしている」という 状況 (Context) を表 現する 「何が出来るべきなのか」という 能力 (Capability)
を表現する 「何を操作しようとしているのか」という 部品 (Component) を表現する 9
Context 状況を表現する 10
Context(状況) いま、どのページにいるのか いま、どのユーザーでログインしているのか etc 11
ある ECサイトのテストコード I.click('購入に進む') // 商品購入画面へ遷移 I.click('決済方法を選択') '購入に進む ' をクリックすると画面遷移が期待されているが、 コードでは表されていない状態
ページ遷移に失敗すると、 決済方法を選択 要素が存在せずエラーになるが、 欲を言うと 期待したページに遷移していない エラーで失敗してほしい 12
Contextをコードで表現する I.click('購入に進む') I.shouldBeOnPurchasePage(I => { I.click('決済方法を選択') }) 13
実装はシンプル shouldBeOnPurchasePage(fn) { I.seeInUrl('/purchase') fn(I) } 14
その他の使い道 : ログイン状態を表現する amStoreStaff(fn) { const I = actor({}); session('StoreStaff',
() => { I.amOnPage("/"); I.click("ログインする"); I.fillField("ユーザー名", "admin"); I.fillField("パスワード", "admin"); I.click("ログイン"); fn(I) }) }, amAnonimousUser(fn) { const I = actor({}); session('AnonimousUser', () => { fn(I) }) } 15
Capability (前提条件として)何が出来るべきか 16
ある ECサイトのテストデータ準備コード const itemName = `牛ハラミ弁当-テスト-${utils.now.format("YYYYMMDDHHmmss")}`; I.amOnPage('/items/add') I.seeInTitle('商品追加') I.fillField("商品名", itemName);
I.fillField("商品説明", "テスト用の商品です"); I.fillField("価格", "500"); I.fillField("在庫数", "10") I.click("追加"); 17
I.canPurchaseItem テストデータが準備されている状態が重要なので、手順は隠蔽する I can purchase item (商品を購入できる)という前提条件として記述する const itemName =
`テスト商品-${Date.now()}` I.canPurchaseItem(itemName) // 商品を購入する I.click(itemName) 18
canPurchaseItem の実装例 canPurchaseItem: (name) { const I = actor({}); if
(!name) name = `牛ハラミ弁当-テスト-${utils.now.format("YYYYMMDDHHmmss")}`; I.amOnPage('/items/add') I.seeInTitle('商品追加') I.fillField("商品名", name); I.fillField("商品説明", "テスト用の商品です"); I.fillField("価格", "500"); I.click("追加"); I.see(name) return name; } 19
Component ページ内のコンポーネントを抽象化する 20
UIコンポーネントを抽象化する <h3> ハムエッグの材料 </h3> <table> <tr> <th> 卵 </th> <td>
1個 </td> <td><button>購入</button></td> </tr> <tr> <th> ハム </th> <td> 2枚 </td> <td><button>購入</button></td> </tr> </table> const row(header) { return locate('tr').withChild( locate('th').withText(header) ) } 21
<h3> ハムエッグの材料 </h3> <table> <tr> <th> 卵 </th> <td> 1個
</td> <td><button>購入</button></td> </tr> <tr> <th> ハム </th> <td> 2枚 </td> <td><button>購入</button></td> </tr> </table> within(row('ハム'), () => { I.click('購入') }) 22
アンチパターン : 操作と要素探索をまとめてしまう I.purchaseHam() I.purchaseEgg() purchase ("購入 " ボタンのクリック )
と Ham/Egg (購入する商品)をまとめたメソッドを作っている 中で何をしているのかが分からなくなる 項目の数だけメソッドを定義しなければならなくなる 23
まとめ E2Eテストの認知負荷を下げるには "3つの C" を理解しよう Context(状況) Capability(能力≒前提条件) Component(部品) ユーザー目線で抽象化していくことで、コメントに頼らずテストコードが書ける CodeceptJSはいいぞ(今日何の会だっけ?)
24
Enjoy Testing! 25