Upgrade to Pro — share decks privately, control downloads, hide ads and more …

リーダブルなE2Eテストコードのための3つのC

tsuemura
August 08, 2024
900

 リーダブルなE2Eテストコードのための3つのC

Playwright本出版記念!Node学園 43時限目 2024-08-08

https://nodejs.connpass.com/event/325813/

tsuemura

August 08, 2024
Tweet

Transcript

  1. 宣伝だ テスト自動化実践ガイド CodeceptJS + Playwright の組み合わせ で E2Eテストを書く テスト自動化を始める前から運用まで広 くカバー

    ハンズオンのためにゴミみたいなアプリ を頑張って作りました ゴミみたいなアプリに自動テストを 書かないといけない場合に便利 3
  2. 今日話すこと E2Eテストの認知負荷の話 認知負荷を下げる 3つの C Context Capability Component これらを CodeceptJSや

    Playwrightでどう表現するか 説明は CodeceptJSでやりますが Playwrightでもできます(たぶん) 書籍ではハンズオンパートの最後に説明があります 3つの Cという言葉は出版後に思いついたので今回が初出です 6
  3. ある ECサイトのテストコード I.click('購入に進む') // 商品購入画面へ遷移 I.click('決済方法を選択') '購入に進む ' をクリックすると画面遷移が期待されているが、 コードでは表されていない状態

    ページ遷移に失敗すると、 決済方法を選択 要素が存在せずエラーになるが、 欲を言うと 期待したページに遷移していない エラーで失敗してほしい 12
  4. その他の使い道 : ログイン状態を表現する 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
  5. 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
  6. 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
  7. <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
  8. アンチパターン : 操作と要素探索をまとめてしまう I.purchaseHam() I.purchaseEgg() purchase ("購入 " ボタンのクリック )

    と Ham/Egg (購入する商品)をまとめたメソッドを作っている 中で何をしているのかが分からなくなる 項目の数だけメソッドを定義しなければならなくなる 23