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

全部乗せフレームワーク CodeceptJS でE2Eテストを楽にしよう

tsuemura
December 05, 2020

全部乗せフレームワーク CodeceptJS でE2Eテストを楽にしよう

ソフトウェアテスト自動化カンファレンス2020
https://testautomationresearch.connpass.com/event/191996/

tsuemura

December 05, 2020
Tweet

More Decks by tsuemura

Other Decks in Technology

Transcript

  1. "全部乗せ" フレームワーク CodeceptJS で
    E2Eテストを楽にしよう
    Takuya Suemura @ Autify, Inc.

    View Slide

  2. 今⽇話すこと
    フレームワーク選定についての話
    CodeceptJSの機能の紹介
    (おまけで)OSS貢献についてちょっとだけ
    話さないこと
    細かいインストール⼿順など
    公式サイトが超分かりやすいので省略します https://codecept.io/
    その他
    スライドは公開します
    サンプルコードも公開予定です

    View Slide

  3. ⾃⼰紹介
    末村 拓也 (すえむら たくや)
    Twitter: @tsueeemura
    Autify テスト⾃動化スペシャリスト
    開発者 兼 サポート 兼 エバンジェリスト
    CodeceptJS コントリビュータ

    View Slide

  4. 書いたもの
    SoftwareDesign誌 6〜8⽉号『はじめよ
    う,⾼速E2Eテスト』
    Autify Blog - なぜE2Eテストでidを使うべ
    きではないのか
    Qiita記事いろいろ

    View Slide

  5. Autifyについて
    WebアプリのE2Eテスト⾃動化の
    ためのツール
    AIによるシナリオの⾃動修復
    (セルフヒーリング)
    リアルデバイス & Dockerコンテ
    ナでの実⾏に対応
    コーディング不要で
    誰でもすぐ使える
    https://autify.com

    View Slide

  6. "全部乗せ" フレームワーク CodeceptJS で
    E2Eテストを楽にする
    https://unsplash.com/photos/YnbJwNXy0YQ

    View Slide

  7. E2Eテストは「やりたいこと」だらけ
    ブラウザやモバイルデバイスを使ってリアルなテストをしたい
    メールやファイルダウンロードなどアプリ外のテストをしたい
    APIのテストもしたい

    View Slide

  8. 慣れてくるとやりたいことは更に増える
    SPAでのテスト実⾏を安定させたい
    マニュアルテスト⽤のテストスクリプトを流⽤したい
    様々なデータセットを使って効率よくテストケースを作成したい
    ⾼速にテストを実⾏したい

    View Slide

  9. 今⽇の話が響きそうな⼈
    E2Eテストについての経験が無い、または浅い⼈
    適切な技術選定が出来るほどの知識はないが、
    将来に渡って⻑く使い続けられそうなものを選びたい⼈
    とにかくスタートを切りたい⼈
    幅広いユースケースに対応できる、裾屋が広いツールをおすすめします

    View Slide

  10. 「全部乗せ」の提案
    様々なツール、ライブラリを
    ⼀つのフレームワーク上で
    統⼀されたAPIで操作できる

    View Slide

  11. CodeceptJSについて

    View Slide

  12. CodeceptJSについて
    ウクライナの Michael
    Bodnarchuk ⽒が作成した
    NodeJS製のOSS
    E2Eテストのためのフルスタック
    なフレームワーク
    BDD(振る舞い駆動開発)を強
    く意識したインターフェース
    様々なツール・ライブラリ群を
    ラップし、切り替えて使うこと
    ができる
    https://codecept.io/

    View Slide

  13. 実際に書いてみよう
    テストケース: ログイン
    https://hotel.testplanisphere.dev/ja/ にアクセスする
    "ログイン" をクリックする
    "メールアドレス" に "[email protected]" と⼊⼒する
    "パスワード" に "password" と⼊⼒する
    "Enter" キーを押す

    View Slide

  14. CodeceptJSで書くと
    Scenario('ログインする', ({I}) => {
    // https://hotel.testplanisphere.dev/ja/ にアクセスする
    I.amOnPage('https://hotel.testplanisphere.dev/ja/')
    // "ログイン" をクリックする
    I.click('ログイン')
    // "メールアドレス" に "[email protected]" と⼊⼒する
    I.fillField('メールアドレス', '[email protected]')
    // "パスワード" に "password" と⼊⼒する
    I.fillField('パスワード', 'password')
    // "Enter" キーを押す
    I.pressKey('Enter')
    })

    View Slide

  15. 他にどんなことが出来るのか
    いろいろできるけど代表的なものを紹介
    データドリブンテスト
    ログイン処理の省略
    メールのテスト
    要素の表⽰待ち

    View Slide

  16. Email Password Type
    [email protected] password Admin
    [email protected] [email protected]! Manager
    [email protected] 1234 Editor
    [email protected] !jkdsaiDcbhz Reader
    Go To "/login"
    Input Email
    Input Password
    See Type
    データドリブンテスト
    ⼀つのテストシナリオを複数の
    データで繰り返し実⾏
    ログインやユーザー登録などの
    テストで良く使われる

    View Slide

  17. データドリブンテスト
    let accounts = new DataTable(['メールアドレス', 'パスワード']); // ⾒出しの定義
    accounts.add(['[email protected]', 'password']); // 登録
    accounts.add(['[email protected]', 'pass1234']); // 登録
    // Data() に利⽤したいデータを格納する
    // Use special param `current` to get current data set
    Data(accounts).Scenario('Test Login', ({ I, current }) => {
    I.amOnPage('https://hotel.testplanisphere.dev/ja/')
    I.click('ログイン')
    I.fillField('メールアドレス', current['メールアドレス']); //
    I.fillField('パスワード', current['パスワード']);
    I.pressKey('Enter')
    });

    View Slide

  18. View Slide

  19. データドリブンテスト応⽤: 操作を切り替える

    View Slide

  20. ⼀般会員はプレミアムプランがない

    View Slide

  21. プレミアム会員はプレミアムプランがある

    View Slide

  22. データドリブンテスト応⽤: 操作を切り替える
    前提: ⼀般ユーザーとプレミアムユーザーで実⾏する
    https://hotel.testplanisphere.dev/ja/ にアクセスする
    "ログイン" をクリックする
    "メールアドレス" に "[email protected]" と⼊⼒する
    "パスワード" に "password" と⼊⼒する
    "Enter" キーを押す
    "宿泊予約" をクリックする
    プランの表⽰確認をする
    プレミアム会員には "プレミアムプラン" が表⽰されている
    ⼀般会員には "プレミアムプラン" が表⽰されていない
    単純なデータの変更だけでなく、アサーションタイプの切り替えが必要になる

    View Slide

  23. データドリブンテスト応⽤: 操作を切り替える
    const accounts = [
    {
    'メールアドレス': '[email protected]',
    'パスワード': 'password',
    'ログイン後の処理': (I) => {
    I.see('プレミアムプラン')
    }
    },
    {
    'メールアドレス': '[email protected]',
    'パスワード': 'pass1234',
    'ログイン後の処理': (I) => {
    I.dontSee('プレミアムプラン')
    }
    },
    ]

    View Slide

  24. データドリブンテスト応⽤: 操作を切り替える
    Data(accounts).Scenario('Test Login', ({ I, current }) => {
    I.amOnPage('https://hotel.testplanisphere.dev/ja/')
    I.click('ログイン')
    I.fillField('メールアドレス', current['メールアドレス']);
    I.fillField('パスワード', current['パスワード']);
    I.pressKey('Enter')
    I.click('宿泊予約')
    current['ログイン後の処理'](I) // データテーブル内で定義した処理
    });

    View Slide

  25. 他にどんなことが出来るのか
    いろいろできるけど代表的なものを紹介
    データドリブンテスト
    ログイン処理の省略
    メールのテスト
    要素の表⽰待ち

    View Slide

  26. ログイン処理の省略
    基本的にE2Eテストでは毎回ブラウザのCookieやキャッシュなどをクリアした状態
    でテストを始めている
    前回実⾏したテストから影響を受けることを防ぐためなのでこれ⾃体は良い
    こと
    しかし、毎回ログインの処理が⾛るとテスト実⾏の時間がかかりすぎる
    必要に応じてログイン処理をスキップできる autoLogin プラグインがある
    ログイン直後のセッション情報(Cookieなど)を⾃動で保存、復元できる
    復元したセッション情報でログイン出来ていない場合は⾃動で再度ログインを試
    みる

    View Slide

  27. テストコード
    Scenario('Auto Login', ({ I, login }) => {
    login('ichiro')
    I.click('宿泊予約')
    I.see('プレミアムプラン')
    })
    Scenario('Auto Login2', ({ I, login }) => {
    login('ichiro')
    I.click("宿泊予約");
    I.see("プレミアムプラン");
    })

    View Slide

  28. autoLoginの設定(前半)
    login: 実際にログインする際に使う⼿順
    check: ログインされているかどうかの判定の⼿順
    // codecept.conf.js
    autoLogin: {
    enabled: true,
    users: {
    ichiro: {
    login: (I) => {
    I.amOnPage("https://hotel.testplanisphere.dev/ja/login.html");
    I.fillField("メールアドレス", "[email protected]");
    I.fillField("パスワード", "password");
    I.pressKey('Enter');
    },
    check: (I) => {
    I.amOnPage("https://hotel.testplanisphere.dev/ja/login.html");
    I.see("ログアウト");
    },

    View Slide

  29. autoLoginの設定(後半)
    fetch: ログインが完了した後、どのようにセッション情報を取得するかの⼿順
    restore: セッションを復元する⼿順
    fetch: async (I) => {
    return await I.grabCookie();
    },
    restore: (I, cookie) => {
    I.amOnPage("https://hotel.testplanisphere.dev/ja/index.html");
    I.setCookie(cookie);
    },
    },
    },
    },

    View Slide

  30. View Slide

  31. 他にどんなことが出来るのか
    いろいろできるけど代表的なものを紹介
    データドリブンテスト
    ログイン処理の省略
    メールのテスト
    要素の表⽰待ち

    View Slide

  32. メールのテストもできる
    MailSlurp(https://www.mailslurp.com/)と連携してメールのテストが出来る
    MailSlurpはメールテストのためのSaaS
    テスト⽤のメールアドレスを作成できる
    WebのUIやAPIを使って届いたメールを確認できる

    View Slide

  33. 事前準備
    MailSlurpのアカウントを作る
    APIトークンを設定する
    // codecept.conf.js
    helpers: {
    MailSlurp: {
    require: '@codeceptjs/mailslurp-helper',
    apiKey: ''
    }
    }

    View Slide

  34. 例)ユーザー登録時のメールアドレス確認をする
    Scenario('create new account', async ({ I }) => {
    // 新しいメールアドレスを MailSlurpに登録する
    const mailbox = await I.haveNewMailbox();
    // Webブラウザ側でユーザー登録処理をする
    I.fillField("メールアドレス", mailbox.emailAddress);
    I.click("送信");
    // 条件に合うメールが届くまで待つ
    const email = await I.waitForEmailMatching({ subject: "メールアドレスの確認" });
    // メール本⽂からURLを抽出する
    const url = email.body.match(/http(s):\/\/(.*?)\s/)[0];
    // ブラウザでURLを開く
    I.amOnPage(url);
    })

    View Slide

  35. 他にどんなことが出来るのか
    いろいろできるけど代表的なものを紹介
    データドリブンテスト
    ログイン処理の省略
    メールのテスト
    要素の表⽰待ち

    View Slide

  36. 要素の表⽰を勝⼿に待ってくれる
    デフォルトで retryFailedStep がONになっている
    retryFailedStep: {
    enabled: true,
    },
    操作対象の要素が存在しなかった場合などに⾃動的にリトライしてくれる
    ステップが対象
    シナリオ単位のリトライは別に存在する

    View Slide

  37. 他のフレームワークとの違い
    厳密には 要素の表⽰ ではなく 操作の成功 を条件にリトライをするため
    次のようなパターンにも対応できる
    検証対象の⽂字列が動的に変更される
    「処理中です……」から「処理が完了しました」に変わるようなイメージ
    操作対象の要素がクリックできない
    要素の上に別の要素が覆いかぶさっている
    要素が⾮表⽰になっている
    button要素などに disabled 属性が付いている

    View Slide

  38. その他の細かい機能たち
    並列実⾏
    ファイルシステムのテスト
    APIのテスト
    いい感じのテスト結果表⽰
    TypeScriptサポート
    Page Objectのサポート
    柔軟で読みやすいロケータ
    詳しく聞きたい⼈はAsk the speakerで︕

    View Slide

  39. ⾜りない機能があったら︖

    View Slide

  40. こんなことがありました
    テストデータ作成のためにステージングサーバ内のコマンドを実⾏したかった
    // こんなのや
    $ artisan createTestUser 100
    // こんなの
    $ bundle exec rake createTestUser 100
    メールのテストに使っていた mailhog に対応するヘルパーがなかった

    View Slide

  41. 作りました

    View Slide

  42. Helperの開発は超簡単
    コマンド⼀発でboilerplateが出来る
    $ npx codeceptjs gh
    const Helper = require('@codeceptjs/helper');
    class MyHelper extends Helper {
    doAwesomeThings() {
    console.log('Hello from MyHelpr');
    }
    }

    View Slide

  43. Helperを作るとCommunity Helperとして載せてもらえる

    View Slide

  44. まとめ
    E2Eテストはやりたいことだらけ
    フルスタックなフレームワークを使うと後からやりたいことが変わっても対応し
    やすい
    CodeceptJSはとても良い選択肢
    無いものは⾃分で作ろう(思ったより簡単だよ︕)

    View Slide

  45. Enjoy Testing!
    ご清聴ありがとうございました

    View Slide