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

退屈なブラウザテストはCodeceptJSにやらせよう

tsuemura
March 24, 2019

 退屈なブラウザテストはCodeceptJSにやらせよう

2019/3/24 SeleniumConf Tokyo 2019 事前勉強会

tsuemura

March 24, 2019
Tweet

More Decks by tsuemura

Other Decks in Technology

Transcript

  1. 退屈なブラウザテストは
    退屈なブラウザテストは
    退屈なブラウザテストは
    退屈なブラウザテストは
    退屈なブラウザテストは
    退屈なブラウザテストは
    CodeceptJS
    にやらせよう
    CodeceptJS
    にやらせよう
    CodeceptJS
    にやらせよう
    CodeceptJS
    にやらせよう
    CodeceptJS
    にやらせよう
    CodeceptJS
    にやらせよう
    末村 拓也 @
    株式会社オープンロジ
    末村 拓也 @
    株式会社オープンロジ
    末村 拓也 @
    株式会社オープンロジ
    末村 拓也 @
    株式会社オープンロジ
    末村 拓也 @
    株式会社オープンロジ
    末村 拓也 @
    株式会社オープンロジ
    1 / 72

    View Slide

  2. はじめまして
    はじめまして
    はじめまして
    はじめまして
    はじめまして
    はじめまして
    末村 拓也(すえむら たくや)
    末村 拓也(すえむら たくや)
    末村 拓也(すえむら たくや)
    末村 拓也(すえむら たくや)
    末村 拓也(すえむら たくや)
    末村 拓也(すえむら たくや)
    物流スタートアップ「OPENLOGI
    」のQA
    エンジニア
    物流スタートアップ「OPENLOGI
    」のQA
    エンジニア
    物流スタートアップ「OPENLOGI
    」のQA
    エンジニア
    物流スタートアップ「OPENLOGI
    」のQA
    エンジニア
    物流スタートアップ「OPENLOGI
    」のQA
    エンジニア
    物流スタートアップ「OPENLOGI
    」のQA
    エンジニア
    です
    です
    です
    です
    です
    です
    まんがとヒトカラがすきです
    まんがとヒトカラがすきです
    まんがとヒトカラがすきです
    まんがとヒトカラがすきです
    まんがとヒトカラがすきです
    まんがとヒトカラがすきです


















    2 / 72

    View Slide

  3. エンジニア歴短めです
    エンジニア歴短めです
    エンジニア歴短めです
    エンジニア歴短めです
    エンジニア歴短めです
    エンジニア歴短めです
    新卒から5
    年間ぐらいフォークリフト乗ってました
    新卒から5
    年間ぐらいフォークリフト乗ってました
    新卒から5
    年間ぐらいフォークリフト乗ってました
    新卒から5
    年間ぐらいフォークリフト乗ってました
    新卒から5
    年間ぐらいフォークリフト乗ってました
    新卒から5
    年間ぐらいフォークリフト乗ってました
    エンジニアを名乗り始めたのはここ3
    年ぐらい
    エンジニアを名乗り始めたのはここ3
    年ぐらい
    エンジニアを名乗り始めたのはここ3
    年ぐらい
    エンジニアを名乗り始めたのはここ3
    年ぐらい
    エンジニアを名乗り始めたのはここ3
    年ぐらい
    エンジニアを名乗り始めたのはここ3
    年ぐらい
    3 / 72

    View Slide

  4. バズりました
    バズりました
    バズりました
    バズりました
    バズりました
    バズりました
    https://qiita.com/tsuemura/items/56ba9942565963858d8f
    https://qiita.com/tsuemura/items/56ba9942565963858d8f
    https://qiita.com/tsuemura/items/56ba9942565963858d8f
    https://qiita.com/tsuemura/items/56ba9942565963858d8f
    https://qiita.com/tsuemura/items/56ba9942565963858d8f
    https://qiita.com/tsuemura/items/56ba9942565963858d8f
    4 / 72

    View Slide

  5. 今日はこの記事で登場した技術を使って
    今日はこの記事で登場した技術を使って
    今日はこの記事で登場した技術を使って
    今日はこの記事で登場した技術を使って
    今日はこの記事で登場した技術を使って
    今日はこの記事で登場した技術を使って
    ブラウザテスト自動化を
    ブラウザテスト自動化を
    ブラウザテスト自動化を
    ブラウザテスト自動化を
    ブラウザテスト自動化を
    ブラウザテスト自動化を
    圧倒的に効率化していきます
    圧倒的に効率化していきます
    圧倒的に効率化していきます
    圧倒的に効率化していきます
    圧倒的に効率化していきます
    圧倒的に効率化していきます
    (記事を読んでいない方もお楽しみいただけます)
    (記事を読んでいない方もお楽しみいただけます)
    (記事を読んでいない方もお楽しみいただけます)
    (記事を読んでいない方もお楽しみいただけます)
    (記事を読んでいない方もお楽しみいただけます)
    (記事を読んでいない方もお楽しみいただけます)
    5 / 72

    View Slide

  6. 記事ではPuppeteer
    を使いましたが
    記事ではPuppeteer
    を使いましたが
    記事ではPuppeteer
    を使いましたが
    記事ではPuppeteer
    を使いましたが
    記事ではPuppeteer
    を使いましたが
    記事ではPuppeteer
    を使いましたが
    このセッションではSelenium
    を使います
    このセッションではSelenium
    を使います
    このセッションではSelenium
    を使います
    このセッションではSelenium
    を使います
    このセッションではSelenium
    を使います
    このセッションではSelenium
    を使います
    6 / 72

    View Slide

  7. 突然ですが
    突然ですが
    突然ですが
    突然ですが
    突然ですが
    突然ですが
    7 / 72

    View Slide

  8. 皆さん
    皆さん
    皆さん
    皆さん
    皆さん
    皆さん
    ブラウザテスト
    ブラウザテスト
    ブラウザテスト
    ブラウザテスト
    ブラウザテスト
    ブラウザテスト
    自動化してますか?
    自動化してますか?
    自動化してますか?
    自動化してますか?
    自動化してますか?
    自動化してますか?
    8 / 72

    View Slide

  9. ブラウザテスト書くの
    ブラウザテスト書くの
    ブラウザテスト書くの
    ブラウザテスト書くの
    ブラウザテスト書くの
    ブラウザテスト書くの
    めんどくさくないですか?
    めんどくさくないですか?
    めんどくさくないですか?
    めんどくさくないですか?
    めんどくさくないですか?
    めんどくさくないですか?
    9 / 72

    View Slide

  10. 例えば
    例えば
    例えば
    例えば
    例えば
    例えば
    10 / 72

    View Slide

  11. セレクタを書くのがめんどくさい
    セレクタを書くのがめんどくさい
    セレクタを書くのがめんどくさい
    セレクタを書くのがめんどくさい
    セレクタを書くのがめんどくさい
    セレクタを書くのがめんどくさい
    11 / 72

    View Slide

  12. 12 / 72

    View Slide

  13. 13 / 72

    View Slide

  14. たかがボタンひとつクリックするために
    たかがボタンひとつクリックするために
    たかがボタンひとつクリックするために
    たかがボタンひとつクリックするために
    たかがボタンひとつクリックするために
    たかがボタンひとつクリックするために
    めんどくさいこと考えたくないですね
    めんどくさいこと考えたくないですね
    めんどくさいこと考えたくないですね
    めんどくさいこと考えたくないですね
    めんどくさいこと考えたくないですね
    めんどくさいこと考えたくないですね
    14 / 72

    View Slide

  15. それから
    それから
    それから
    それから
    それから
    それから
    15 / 72

    View Slide

  16. 要素の表示待ちを
    要素の表示待ちを
    要素の表示待ちを
    要素の表示待ちを
    要素の表示待ちを
    要素の表示待ちを
    考えるのが面倒
    考えるのが面倒
    考えるのが面倒
    考えるのが面倒
    考えるのが面倒
    考えるのが面倒
    16 / 72

    View Slide

  17. 17 / 72

    View Slide

  18. 18 / 72

    View Slide

  19. 言わなくても待ってて欲しいですね
    言わなくても待ってて欲しいですね
    言わなくても待ってて欲しいですね
    言わなくても待ってて欲しいですね
    言わなくても待ってて欲しいですね
    言わなくても待ってて欲しいですね
    (Implicitly Wait
    でもいいんだけど有効範囲が限定的なイメージ)
    (Implicitly Wait
    でもいいんだけど有効範囲が限定的なイメージ)
    (Implicitly Wait
    でもいいんだけど有効範囲が限定的なイメージ)
    (Implicitly Wait
    でもいいんだけど有効範囲が限定的なイメージ)
    (Implicitly Wait
    でもいいんだけど有効範囲が限定的なイメージ)
    (Implicitly Wait
    でもいいんだけど有効範囲が限定的なイメージ)
    19 / 72

    View Slide

  20. さらにさらに
    さらにさらに
    さらにさらに
    さらにさらに
    さらにさらに
    さらにさらに
    20 / 72

    View Slide

  21. デバッグがめんどくさい
    デバッグがめんどくさい
    デバッグがめんどくさい
    デバッグがめんどくさい
    デバッグがめんどくさい
    デバッグがめんどくさい
    21 / 72

    View Slide

  22. 22 / 72

    View Slide

  23. 23 / 72

    View Slide

  24. デバッグなんてしなくてもすむように
    デバッグなんてしなくてもすむように
    デバッグなんてしなくてもすむように
    デバッグなんてしなくてもすむように
    デバッグなんてしなくてもすむように
    デバッグなんてしなくてもすむように
    最初から動くコードを書きたいですね!!
    最初から動くコードを書きたいですね!!
    最初から動くコードを書きたいですね!!
    最初から動くコードを書きたいですね!!
    最初から動くコードを書きたいですね!!
    最初から動くコードを書きたいですね!!
    24 / 72

    View Slide

  25. どうすれば簡単に書けるんでしょうか
    どうすれば簡単に書けるんでしょうか
    どうすれば簡単に書けるんでしょうか
    どうすれば簡単に書けるんでしょうか
    どうすれば簡単に書けるんでしょうか
    どうすれば簡単に書けるんでしょうか
    25 / 72

    View Slide

  26. __.. -
    ―─ 、__
    __.. -
    ―─ 、__
    /` 三ミー ヘ、_
    /` 三ミー ヘ、_
    ゝ' ;; ,, , ,,
    ミミ , il
    ゙Z,
    ゝ' ;; ,, , ,,
    ミミ , il
    ゙Z,
    _
    〉,.. ////, ,
    彡ff
    ッィ彡从j

    _
    〉,.. ////, ,
    彡ff
    ッィ彡从j

    〉,
    ィiiif , ,, '
    ノ川j
    ノ川; :.
    `フ公)

    〉,
    ィiiif , ,, '
    ノ川j
    ノ川; :.
    `フ公)

    \.:.:.:i=
    珍/二''=
    く、 !
    ノ一ヾ゙;.;.;

    \.:.:.:i=
    珍/二''=
    く、 !
    ノ一ヾ゙;.;.;

    く:.:.:.:l
    ムj
    イ rf
    モテ〉゙} ij
    ィt
    ケ 1
    イ'´
    く:.:.:.:l
    ムj
    イ rf
    モテ〉゙} ij
    ィt
    ケ 1
    イ'´
    〕:.:.|,Y!:!
    、 ニ '
    、 ; |
    `ニ イj'
    逆に考えるんだ
    〕:.:.|,Y!:!
    、 ニ '
    、 ; |
    `ニ イj'
    逆に考えるんだ
    {:.:.:j {: :}
    ` 、_{__} /

    {:.:.:j {: :}
    ` 、_{__} /

    〉イ 、゙! ,
    ィ__
    三ー、 j
    ′ 「これらをやらなければテストは楽に書けるはずさ」
    〉イ 、゙! ,
    ィ__
    三ー、 j
    ′ 「これらをやらなければテストは楽に書けるはずさ」
    ,{
    \ ミ \ ゝ'
    ェェ'
    `' /
    ,{
    \ ミ \ ゝ'
    ェェ'
    `' /
    -‐'
    \ \ ヽ\ 彡 イ-
    、 と考えるんだ
    -‐'
    \ \ ヽ\ 彡 イ-
    、 と考えるんだ
    \ \.
    ヽゝ‐‐‐
    升 ト、 ヽ、__
    \ \.
    ヽゝ‐‐‐
    升 ト、 ヽ、__
    \ ヽ-
    、./
    / j!:.}
    ` ー 、
    \ ヽ-
    、./
    / j!:.}
    ` ー 、
    ヽ\ 厶_r__
    ハ/!:.{
    ヽ\ 厶_r__
    ハ/!:.{
    ´ / !

    ´ / !

    26 / 72

    View Slide

  27. 裏を返せば
    裏を返せば
    裏を返せば
    裏を返せば
    裏を返せば
    裏を返せば
    これらをやらなければ
    これらをやらなければ
    これらをやらなければ
    これらをやらなければ
    これらをやらなければ
    これらをやらなければ
    テストは楽に書ける(はず)
    テストは楽に書ける(はず)
    テストは楽に書ける(はず)
    テストは楽に書ける(はず)
    テストは楽に書ける(はず)
    テストは楽に書ける(はず)
    27 / 72

    View Slide

  28. ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く


















    28 / 72

    View Slide

  29. これ全部できます。
    これ全部できます。
    これ全部できます。
    これ全部できます。
    これ全部できます。
    これ全部できます。
    そう、CodeceptJS
    ならね
    そう、CodeceptJS
    ならね
    そう、CodeceptJS
    ならね
    そう、CodeceptJS
    ならね
    そう、CodeceptJS
    ならね
    そう、CodeceptJS
    ならね
    29 / 72

    View Slide

  30. CodeceptJS
    ってなんなの?
    CodeceptJS
    ってなんなの?
    CodeceptJS
    ってなんなの?
    CodeceptJS
    ってなんなの?
    CodeceptJS
    ってなんなの?
    CodeceptJS
    ってなんなの?
    https://codecept.io
    https://codecept.io
    https://codecept.io
    https://codecept.io
    https://codecept.io
    https://codecept.io
    NodeJS
    製のブラウザテストフレームワーク
    NodeJS
    製のブラウザテストフレームワーク
    NodeJS
    製のブラウザテストフレームワーク
    NodeJS
    製のブラウザテストフレームワーク
    NodeJS
    製のブラウザテストフレームワーク
    NodeJS
    製のブラウザテストフレームワーク
    他のブラウザ操作フレームワークと組み合わせる
    他のブラウザ操作フレームワークと組み合わせる
    他のブラウザ操作フレームワークと組み合わせる
    他のブラウザ操作フレームワークと組み合わせる
    他のブラウザ操作フレームワークと組み合わせる
    他のブラウザ操作フレームワークと組み合わせる
    ことでブラウザやモバイル実機を操作できる
    ことでブラウザやモバイル実機を操作できる
    ことでブラウザやモバイル実機を操作できる
    ことでブラウザやモバイル実機を操作できる
    ことでブラウザやモバイル実機を操作できる
    ことでブラウザやモバイル実機を操作できる
    受け入れテストを直感的に分かりやすく書くこと
    受け入れテストを直感的に分かりやすく書くこと
    受け入れテストを直感的に分かりやすく書くこと
    受け入れテストを直感的に分かりやすく書くこと
    受け入れテストを直感的に分かりやすく書くこと
    受け入れテストを直感的に分かりやすく書くこと
    に注力している
    に注力している
    に注力している
    に注力している
    に注力している
    に注力している


















    30 / 72

    View Slide

  31. 同じ文法で複数のドライバを利用できる
    同じ文法で複数のドライバを利用できる
    同じ文法で複数のドライバを利用できる
    同じ文法で複数のドライバを利用できる
    同じ文法で複数のドライバを利用できる
    同じ文法で複数のドライバを利用できる
    31 / 72

    View Slide

  32. CodeceptJS
    の様々な機能の中から
    CodeceptJS
    の様々な機能の中から
    CodeceptJS
    の様々な機能の中から
    CodeceptJS
    の様々な機能の中から
    CodeceptJS
    の様々な機能の中から
    CodeceptJS
    の様々な機能の中から
    ブラウザテスト記述を特に楽にしてくれる
    ブラウザテスト記述を特に楽にしてくれる
    ブラウザテスト記述を特に楽にしてくれる
    ブラウザテスト記述を特に楽にしてくれる
    ブラウザテスト記述を特に楽にしてくれる
    ブラウザテスト記述を特に楽にしてくれる
    3
    つの機能を紹介します
    3
    つの機能を紹介します
    3
    つの機能を紹介します
    3
    つの機能を紹介します
    3
    つの機能を紹介します
    3
    つの機能を紹介します
    Semantic Locator
    Semantic Locator
    Semantic Locator
    Semantic Locator
    Semantic Locator
    Semantic Locator
    retryFailedStep Plugin
    retryFailedStep Plugin
    retryFailedStep Plugin
    retryFailedStep Plugin
    retryFailedStep Plugin
    retryFailedStep Plugin
    Debugger
    Debugger
    Debugger
    Debugger
    Debugger
    Debugger


















    32 / 72

    View Slide

  33. さっそく使ってみましょう
    さっそく使ってみましょう
    さっそく使ってみましょう
    さっそく使ってみましょう
    さっそく使ってみましょう
    さっそく使ってみましょう
    33 / 72

    View Slide

  34. まずは準備
    まずは準備
    まずは準備
    まずは準備
    まずは準備
    まずは準備
    34 / 72

    View Slide

  35. 必要なもの
    必要なもの
    必要なもの
    必要なもの
    必要なもの
    必要なもの
    NodeJS v8.9
    以上
    NodeJS v8.9
    以上
    NodeJS v8.9
    以上
    NodeJS v8.9
    以上
    NodeJS v8.9
    以上
    NodeJS v8.9
    以上
    npm
    npm
    npm
    npm
    npm
    npm
    Javascript
    チョット デキル
    Javascript
    チョット デキル
    Javascript
    チョット デキル
    Javascript
    チョット デキル
    Javascript
    チョット デキル
    Javascript
    チョット デキル
    UNIX
    系OS
    前提で話しますが
    UNIX
    系OS
    前提で話しますが
    UNIX
    系OS
    前提で話しますが
    UNIX
    系OS
    前提で話しますが
    UNIX
    系OS
    前提で話しますが
    UNIX
    系OS
    前提で話しますが
    Windows
    でも普通に動く(はず)
    Windows
    でも普通に動く(はず)
    Windows
    でも普通に動く(はず)
    Windows
    でも普通に動く(はず)
    Windows
    でも普通に動く(はず)
    Windows
    でも普通に動く(はず)


















    35 / 72

    View Slide

  36. インストールは簡単です
    インストールは簡単です
    インストールは簡単です
    インストールは簡単です
    インストールは簡単です
    インストールは簡単です
    $
    $ mkdir
    mkdir sample
    sample &&
    && cd
    cd sample
    sample
    $
    $ npm
    npm init
    init
    # Enter
    連打!!!!!
    # Enter
    連打!!!!!
    $
    $ npm
    npm install
    install codeceptjs webdriverio
    codeceptjs webdriverio
    $ npx codeceptjs init
    $ npx codeceptjs init
    # Enter
    連打!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    # Enter
    連打!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    36 / 72

    View Slide

  37. Selenium Server
    Selenium Server
    Selenium Server
    Selenium Server
    Selenium Server
    Selenium Server
    別途インストールし起動しておいてください
    別途インストールし起動しておいてください
    別途インストールし起動しておいてください
    別途インストールし起動しておいてください
    別途インストールし起動しておいてください
    別途インストールし起動しておいてください
    やりかたがわからない方向け
    やりかたがわからない方向け
    やりかたがわからない方向け
    やりかたがわからない方向け
    やりかたがわからない方向け
    やりかたがわからない方向け
    $
    $ sudo
    sudo npm
    npm install
    install -g selenium-standalone
    -g selenium-standalone
    $ selenium-standalone
    $ selenium-standalone install
    install
    $ selenium-standalone start
    $ selenium-standalone start
    37 / 72

    View Slide

  38. 準備完了
    準備完了
    準備完了
    準備完了
    準備完了
    準備完了
    38 / 72

    View Slide

  39. ここでもういちどおさらい
    ここでもういちどおさらい
    ここでもういちどおさらい
    ここでもういちどおさらい
    ここでもういちどおさらい
    ここでもういちどおさらい
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    ブラウザテストを楽に書くコツ
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    CSS
    セレクタやXPath
    を(なるべく)使わない
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    動かなかったら自動でリトライさせる
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く


















    39 / 72

    View Slide

  40. 書く時は
    書く時は
    書く時は
    書く時は
    書く時は
    書く時は
    一行ずつ動かしながら
    一行ずつ動かしながら
    一行ずつ動かしながら
    一行ずつ動かしながら
    一行ずつ動かしながら
    一行ずつ動かしながら
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    動かす時は
    動かす時は
    動かす時は
    動かす時は
    動かす時は
    動かす時は
    動かない時は適宜リトライさせる
    動かない時は適宜リトライさせる
    動かない時は適宜リトライさせる
    動かない時は適宜リトライさせる
    動かない時は適宜リトライさせる
    動かない時は適宜リトライさせる
    という方針でやってみましょう
    という方針でやってみましょう
    という方針でやってみましょう
    という方針でやってみましょう
    という方針でやってみましょう
    という方針でやってみましょう


















    40 / 72

    View Slide

  41. 例として
    例として
    例として
    例として
    例として
    例として
    Github
    のユーザー登録フォームをテストします
    Github
    のユーザー登録フォームをテストします
    Github
    のユーザー登録フォームをテストします
    Github
    のユーザー登録フォームをテストします
    Github
    のユーザー登録フォームをテストします
    Github
    のユーザー登録フォームをテストします
    41 / 72

    View Slide

  42. 一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    一行ずつ動かしながら書く
    $ npx codeceptjs shell
    $ npx codeceptjs shell
    → 対話型コンソールが起動します
    → 対話型コンソールが起動します
    → 対話型コンソールが起動します
    → 対話型コンソールが起動します
    → 対話型コンソールが起動します
    → 対話型コンソールが起動します
    42 / 72

    View Slide

  43. 次のコードを入力していきます
    次のコードを入力していきます
    次のコードを入力していきます
    次のコードを入力していきます
    次のコードを入力していきます
    次のコードを入力していきます
    >
    > I
    I.
    .amOnPage
    amOnPage(
    ('https://github.com'
    'https://github.com')
    )
    >
    > I
    I.
    .fillField
    fillField(
    ('Username'
    'Username',
    , 'shen-long1234'
    'shen-long1234')
    )
    >
    > I
    I.
    .fillField
    fillField(
    ('Email'
    'Email',
    , '[email protected]'
    '[email protected]')
    )
    >
    > I
    I.
    .fillField
    fillField(
    ('Password'
    'Password',
    , 'P@ssword1234'
    'P@ssword1234')
    )
    >
    > I
    I.
    .click
    click(
    ('Sign up for GitHub'
    'Sign up for GitHub')
    )
    43 / 72

    View Slide

  44. 動きましたね
    動きましたね
    動きましたね
    動きましたね
    動きましたね
    動きましたね
    44 / 72

    View Slide

  45. 動いたのでそのままコピペして
    動いたのでそのままコピペして
    動いたのでそのままコピペして
    動いたのでそのままコピペして
    動いたのでそのままコピペして
    動いたのでそのままコピペして
    再実行しましょう
    再実行しましょう
    再実行しましょう
    再実行しましょう
    再実行しましょう
    再実行しましょう
    Feature
    Feature(
    ('Github'
    'Github')
    )
    Scenario
    Scenario(
    ('Can Sign Up'
    'Can Sign Up',
    , async
    async (
    (I
    I)
    ) =>
    => {
    {
    I
    I.
    .amOnPage
    amOnPage(
    ('https://github.com'
    'https://github.com')
    )
    I
    I.
    .fillField
    fillField(
    ('Username'
    'Username',
    , 'shen-long1234'
    'shen-long1234')
    )
    I
    I.
    .fillField
    fillField(
    ('Email'
    'Email',
    , '[email protected]'
    '[email protected]')
    )
    I
    I.
    .fillField
    fillField(
    ('Password'
    'Password',
    , 'P@ssword1234'
    'P@ssword1234')
    )
    I
    I.
    .click
    click(
    ('Sign up for GitHub'
    'Sign up for GitHub')
    )
    }
    })
    )





    → github_test.js
    github_test.js
    github_test.js
    github_test.js
    github_test.js
    github_test.js
    として保存
    として保存
    として保存
    として保存
    として保存
    として保存
    45 / 72

    View Slide

  46. 実行
    実行
    実行
    実行
    実行
    実行
    $ npx codeceptjs run github_test.js --steps
    $ npx codeceptjs run github_test.js --steps
    Github --
    Github --
    Can Sign Up
    Can Sign Up
    I am on page "https://github.com"
    I am on page "https://github.com"
    I fill field "Username", "shen-long1234"
    I fill field "Username", "shen-long1234"
    I fill field "Email", "[email protected]"
    I fill field "Email", "[email protected]"
    I fill field "Password", "P@ssword1234"
    I fill field "Password", "P@ssword1234"
    I click "Sign up for GitHub"
    I click "Sign up for GitHub"
    ✔ OK in 5593ms
    ✔ OK in 5593ms
    46 / 72

    View Slide

  47. ここでもう一度コードを見てみます
    ここでもう一度コードを見てみます
    ここでもう一度コードを見てみます
    ここでもう一度コードを見てみます
    ここでもう一度コードを見てみます
    ここでもう一度コードを見てみます
    Feature
    Feature(
    ('Github'
    'Github')
    )
    Scenario
    Scenario(
    ('Can Sign Up'
    'Can Sign Up',
    , async
    async (
    (I
    I)
    ) =>
    => {
    {
    I
    I.
    .amOnPage
    amOnPage(
    ('https://github.com'
    'https://github.com')
    )
    I
    I.
    .fillField
    fillField(
    ('Username'
    'Username',
    , 'shen-long1234'
    'shen-long1234')
    )
    I
    I.
    .fillField
    fillField(
    ('Email'
    'Email',
    , '[email protected]'
    '[email protected]')
    )
    I
    I.
    .fillField
    fillField(
    ('Password'
    'Password',
    , 'P@ssword1234'
    'P@ssword1234')
    )
    I
    I.
    .click
    click(
    ('Sign up for GitHub'
    'Sign up for GitHub')
    )
    }
    })
    )
    CSS
    セレクタの類は全然出てきませんね
    CSS
    セレクタの類は全然出てきませんね
    CSS
    セレクタの類は全然出てきませんね
    CSS
    セレクタの類は全然出てきませんね
    CSS
    セレクタの類は全然出てきませんね
    CSS
    セレクタの類は全然出てきませんね
    47 / 72

    View Slide

  48. なぜセレクタを書かずに動くの?
    なぜセレクタを書かずに動くの?
    なぜセレクタを書かずに動くの?
    なぜセレクタを書かずに動くの?
    なぜセレクタを書かずに動くの?
    なぜセレクタを書かずに動くの?
    秘密は Semantic Locator
    秘密は Semantic Locator
    秘密は Semantic Locator
    秘密は Semantic Locator
    秘密は Semantic Locator
    秘密は Semantic Locator
    48 / 72

    View Slide

  49. Semantic Locator
    とは
    Semantic Locator
    とは
    Semantic Locator
    とは
    Semantic Locator
    とは
    Semantic Locator
    とは
    Semantic Locator
    とは
    アクションにCSS
    でもXPath
    でもない文字列を渡すと
    アクションにCSS
    でもXPath
    でもない文字列を渡すと
    アクションにCSS
    でもXPath
    でもない文字列を渡すと
    アクションにCSS
    でもXPath
    でもない文字列を渡すと
    アクションにCSS
    でもXPath
    でもない文字列を渡すと
    アクションにCSS
    でもXPath
    でもない文字列を渡すと
    なんか良い感じにその文字列を持つ要素を
    なんか良い感じにその文字列を持つ要素を
    なんか良い感じにその文字列を持つ要素を
    なんか良い感じにその文字列を持つ要素を
    なんか良い感じにその文字列を持つ要素を
    なんか良い感じにその文字列を持つ要素を
    探索してくれる機能
    探索してくれる機能
    探索してくれる機能
    探索してくれる機能
    探索してくれる機能
    探索してくれる機能
    https://codecept.io/locators#semantic-locators
    https://codecept.io/locators#semantic-locators
    https://codecept.io/locators#semantic-locators
    https://codecept.io/locators#semantic-locators
    https://codecept.io/locators#semantic-locators
    https://codecept.io/locators#semantic-locators
    49 / 72

    View Slide

  50. 例えば
    例えば
    例えば
    例えば
    例えば
    例えば
    クリックなら
    クリックなら
    クリックなら
    クリックなら
    クリックなら
    クリックなら


















    のうち指定されたテキストを持つものを探索します
    のうち指定されたテキストを持つものを探索します
    のうち指定されたテキストを持つものを探索します
    のうち指定されたテキストを持つものを探索します
    のうち指定されたテキストを持つものを探索します
    のうち指定されたテキストを持つものを探索します


















    50 / 72

    View Slide

  51. 例えば
    例えば
    例えば
    例えば
    例えば
    例えば
    文字入力なら
    文字入力なら
    文字入力なら
    文字入力なら
    文字入力なら
    文字入力なら












    などのうち、
    などのうち、
    などのうち、
    などのうち、
    などのうち、
    などのうち、 label
    label
    label
    label
    label
    label





    や placeholder
    placeholder
    placeholder
    placeholder
    placeholder
    placeholder





    や name
    name
    name
    name
    name
    name
    などに
    などに
    などに
    などに
    などに
    などに
    指定されたテキストを含むものを
    指定されたテキストを含むものを
    指定されたテキストを含むものを
    指定されたテキストを含むものを
    指定されたテキストを含むものを
    指定されたテキストを含むものを
    自動的に探索します
    自動的に探索します
    自動的に探索します
    自動的に探索します
    自動的に探索します
    自動的に探索します












    51 / 72

    View Slide

  52. 最高
    最高
    最高
    最高
    最高
    最高
    52 / 72

    View Slide

  53. もちろんSemantic Locator

    もちろんSemantic Locator

    もちろんSemantic Locator

    もちろんSemantic Locator

    もちろんSemantic Locator

    もちろんSemantic Locator

    対応できないケースはあります
    対応できないケースはあります
    対応できないケースはあります
    対応できないケースはあります
    対応できないケースはあります
    対応できないケースはあります
    そういうときは割り切って
    そういうときは割り切って
    そういうときは割り切って
    そういうときは割り切って
    そういうときは割り切って
    そういうときは割り切って
    CSS
    セレクタとか使っていきましょう
    CSS
    セレクタとか使っていきましょう
    CSS
    セレクタとか使っていきましょう
    CSS
    セレクタとか使っていきましょう
    CSS
    セレクタとか使っていきましょう
    CSS
    セレクタとか使っていきましょう
    I
    I.
    .click
    click(
    ('#submit'
    '#submit')
    )
    53 / 72

    View Slide

  54. CSS
    セレクタやXPath
    を使わざるを得ない時も
    CSS
    セレクタやXPath
    を使わざるを得ない時も
    CSS
    セレクタやXPath
    を使わざるを得ない時も
    CSS
    セレクタやXPath
    を使わざるを得ない時も
    CSS
    セレクタやXPath
    を使わざるを得ない時も
    CSS
    セレクタやXPath
    を使わざるを得ない時も
    locate
    locate
    locate
    locate
    locate
    locate
    関数を使えば可読性を保ったまま書けます
    関数を使えば可読性を保ったまま書けます
    関数を使えば可読性を保ったまま書けます
    関数を使えば可読性を保ったまま書けます
    関数を使えば可読性を保ったまま書けます
    関数を使えば可読性を保ったまま書けます
    const
    const checkBox
    checkBox =
    = locate
    locate(
    ('input'
    'input')
    )
    .
    .withAttr
    withAttr(
    ({
    {type
    type:
    : 'checkbox'
    'checkbox'}
    })
    )
    .
    .inside
    inside(
    ('form#register'
    'form#register')
    )
    const
    const submit
    submit =
    = locate
    locate(
    ('button'
    'button')
    ).
    .withText
    withText(
    ('
    送信する'
    '
    送信する')
    )
    I
    I.
    .checkOption
    checkOption(
    (checkBox
    checkBox)
    )
    I
    I.
    .click
    click(
    (submit
    submit)
    )
    withText()
    withText()
    withText()
    withText()
    withText()
    withText()
    を使えばSemantic Locator
    がなくても
    を使えばSemantic Locator
    がなくても
    を使えばSemantic Locator
    がなくても
    を使えばSemantic Locator
    がなくても
    を使えばSemantic Locator
    がなくても
    を使えばSemantic Locator
    がなくても
    分かりやすく書けますね
    分かりやすく書けますね
    分かりやすく書けますね
    分かりやすく書けますね
    分かりやすく書けますね
    分かりやすく書けますね
    54 / 72

    View Slide

  55. locate
    locate
    locate
    locate
    locate
    locate
    を使う場合、
    を使う場合、
    を使う場合、
    を使う場合、
    を使う場合、
    を使う場合、as
    as
    as
    as
    as
    as
    メソッドを使うと
    メソッドを使うと
    メソッドを使うと
    メソッドを使うと
    メソッドを使うと
    メソッドを使うと
    ロケータに別名を持たせることができます
    ロケータに別名を持たせることができます
    ロケータに別名を持たせることができます
    ロケータに別名を持たせることができます
    ロケータに別名を持たせることができます
    ロケータに別名を持たせることができます
    const
    const submit
    submit =
    = locate
    locate(
    ('button'
    'button')
    )
    .
    .withText
    withText(
    ('
    送信する'
    '
    送信する')
    )
    .
    .as
    as(
    ('
    送信ボタン'
    '
    送信ボタン')
    )
    I
    I.
    .click
    click(
    (submit
    submit)
    )
    //
    レポートでは `I click
    送信ボタン`
    のように表示される
    //
    レポートでは `I click
    送信ボタン`
    のように表示される
    55 / 72

    View Slide

  56. 特定の要素の内側でのみ探索することもできます
    特定の要素の内側でのみ探索することもできます
    特定の要素の内側でのみ探索することもできます
    特定の要素の内側でのみ探索することもできます
    特定の要素の内側でのみ探索することもできます
    特定の要素の内側でのみ探索することもできます
    const
    const dialog
    dialog =
    = locate
    locate(
    ('div'
    'div')
    )
    .
    .withText
    withText(
    ('
    送信してよろしいですか?'
    '
    送信してよろしいですか?')
    )
    .
    .as
    as(
    ('
    送信確認ダイアログ'
    '
    送信確認ダイアログ')
    )
    //
    送信確認ダイアログの中のみを探索
    //
    送信確認ダイアログの中のみを探索
    with
    with(
    (dialog
    dialog,
    , (
    ()
    ) =>
    => {
    {
    I
    I.
    .click
    click(
    ('
    送信'
    '
    送信')
    )
    }
    })
    )
    56 / 72

    View Slide

  57. locate
    locate
    locate
    locate
    locate
    locate
    の話は
    の話は
    の話は
    の話は
    の話は
    の話は
    永遠に続けられるので
    永遠に続けられるので
    永遠に続けられるので
    永遠に続けられるので
    永遠に続けられるので
    永遠に続けられるので
    いったんここまで!
    いったんここまで!
    いったんここまで!
    いったんここまで!
    いったんここまで!
    いったんここまで!
    (興味のある方は終了後
    (興味のある方は終了後
    (興味のある方は終了後
    (興味のある方は終了後
    (興味のある方は終了後
    (興味のある方は終了後
    またはTwitter
    等でお声がけください)
    またはTwitter
    等でお声がけください)
    またはTwitter
    等でお声がけください)
    またはTwitter
    等でお声がけください)
    またはTwitter
    等でお声がけください)
    またはTwitter
    等でお声がけください)
    57 / 72

    View Slide

  58. ここまでの説明で
    ここまでの説明で
    ここまでの説明で
    ここまでの説明で
    ここまでの説明で
    ここまでの説明で
    動かしながら書くのでデバッグ不要
    動かしながら書くのでデバッグ不要
    動かしながら書くのでデバッグ不要
    動かしながら書くのでデバッグ不要
    動かしながら書くのでデバッグ不要
    動かしながら書くのでデバッグ不要
    CSS
    セレクタやXPath
    を考えずに記述できる
    CSS
    セレクタやXPath
    を考えずに記述できる
    CSS
    セレクタやXPath
    を考えずに記述できる
    CSS
    セレクタやXPath
    を考えずに記述できる
    CSS
    セレクタやXPath
    を考えずに記述できる
    CSS
    セレクタやXPath
    を考えずに記述できる
    ようになりました
    ようになりました
    ようになりました
    ようになりました
    ようになりました
    ようになりました












    58 / 72

    View Slide

  59. まだ大事な課題が残っていますね
    まだ大事な課題が残っていますね
    まだ大事な課題が残っていますね
    まだ大事な課題が残っていますね
    まだ大事な課題が残っていますね
    まだ大事な課題が残っていますね
    59 / 72

    View Slide

  60. 方針のおさらい
    方針のおさらい
    方針のおさらい
    方針のおさらい
    方針のおさらい
    方針のおさらい
    書く時は
    書く時は
    書く時は
    書く時は
    書く時は
    書く時は
    一行ずつ動かしながら
    一行ずつ動かしながら
    一行ずつ動かしながら
    一行ずつ動かしながら
    一行ずつ動かしながら
    一行ずつ動かしながら
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    CSS
    やXPath
    をなるべく使わず
    動かす時は
    動かす時は
    動かす時は
    動かす時は
    動かす時は
    動かす時は
    動かない時は適宜リトライさせる ←未解決
    動かない時は適宜リトライさせる ←未解決
    動かない時は適宜リトライさせる ←未解決
    動かない時は適宜リトライさせる ←未解決
    動かない時は適宜リトライさせる ←未解決
    動かない時は適宜リトライさせる ←未解決


















    60 / 72

    View Slide

  61. 例えば
    例えば
    例えば
    例えば
    例えば
    例えば
    Github
    のユーザー登録フォームで、
    Github
    のユーザー登録フォームで、
    Github
    のユーザー登録フォームで、
    Github
    のユーザー登録フォームで、
    Github
    のユーザー登録フォームで、
    Github
    のユーザー登録フォームで、
    すでに登録済みのユーザー名を入れると
    すでに登録済みのユーザー名を入れると
    すでに登録済みのユーザー名を入れると
    すでに登録済みのユーザー名を入れると
    すでに登録済みのユーザー名を入れると
    すでに登録済みのユーザー名を入れると
    エラーが表示されます
    エラーが表示されます
    エラーが表示されます
    エラーが表示されます
    エラーが表示されます
    エラーが表示されます
    「このエラーが表示されること」をテストします
    「このエラーが表示されること」をテストします
    「このエラーが表示されること」をテストします
    「このエラーが表示されること」をテストします
    「このエラーが表示されること」をテストします
    「このエラーが表示されること」をテストします
    61 / 72

    View Slide

  62. コンソールから書いてみます
    コンソールから書いてみます
    コンソールから書いてみます
    コンソールから書いてみます
    コンソールから書いてみます
    コンソールから書いてみます
    > I.amOnpage('https://github.com')
    > I.amOnpage('https://github.com')
    > I.fillField('Username', 'tsuemura')
    > I.fillField('Username', 'tsuemura')
    > I.see('Something went wrong') //
    エラーが表示されているこ
    > I.see('Something went wrong') //
    エラーが表示されているこ
    とを確認
    とを確認
    これは成功します
    これは成功します
    これは成功します
    これは成功します
    これは成功します
    これは成功します
    62 / 72

    View Slide

  63. このコードを自動実行させてみます
    このコードを自動実行させてみます
    このコードを自動実行させてみます
    このコードを自動実行させてみます
    このコードを自動実行させてみます
    このコードを自動実行させてみます
    Feature
    Feature(
    ('Github'
    'Github')
    )
    Scenario
    Scenario(
    ('Username must be unique'
    'Username must be unique',
    , async
    async (
    (I
    I)
    ) =>
    => {
    {
    I
    I.
    .amOnPage
    amOnPage(
    ('https://github.com'
    'https://github.com')
    )
    I
    I.
    .fillField
    fillField(
    ('Username'
    'Username',
    , 'tsuemura'
    'tsuemura')
    )
    I
    I.
    .see
    see(
    ('Something went wrong'
    'Something went wrong')
    )
    }
    })
    )





    → github2_test.js
    github2_test.js
    github2_test.js
    github2_test.js
    github2_test.js
    github2_test.js
    として保存
    として保存
    として保存
    として保存
    として保存
    として保存
    $ npx codeceptjs run github2_test.js --steps
    $ npx codeceptjs run github2_test.js --steps
    63 / 72

    View Slide

  64. 失敗しました
    失敗しました
    失敗しました
    失敗しました
    失敗しました
    失敗しました
    バリデーションメッセージが出る前に
    バリデーションメッセージが出る前に
    バリデーションメッセージが出る前に
    バリデーションメッセージが出る前に
    バリデーションメッセージが出る前に
    バリデーションメッセージが出る前に
    アサーションしてしまったからですね
    アサーションしてしまったからですね
    アサーションしてしまったからですね
    アサーションしてしまったからですね
    アサーションしてしまったからですね
    アサーションしてしまったからですね
    64 / 72

    View Slide

  65. ここで登場するのが
    ここで登場するのが
    ここで登場するのが
    ここで登場するのが
    ここで登場するのが
    ここで登場するのが
    retryFailedStep
    retryFailedStep
    retryFailedStep
    retryFailedStep
    retryFailedStep
    retryFailedStep
    プラグイン
    プラグイン
    プラグイン
    プラグイン
    プラグイン
    プラグイン
    文字通り「失敗したらリトライする」機能です
    文字通り「失敗したらリトライする」機能です
    文字通り「失敗したらリトライする」機能です
    文字通り「失敗したらリトライする」機能です
    文字通り「失敗したらリトライする」機能です
    文字通り「失敗したらリトライする」機能です
    (デフォルトでは1
    秒ごとに最大5
    回リトライ)
    (デフォルトでは1
    秒ごとに最大5
    回リトライ)
    (デフォルトでは1
    秒ごとに最大5
    回リトライ)
    (デフォルトでは1
    秒ごとに最大5
    回リトライ)
    (デフォルトでは1
    秒ごとに最大5
    回リトライ)
    (デフォルトでは1
    秒ごとに最大5
    回リトライ)
    WebDriver

    WebDriver

    WebDriver

    WebDriver

    WebDriver

    WebDriver
    の implicitly wait
    implicitly wait
    implicitly wait
    implicitly wait
    implicitly wait
    implicitly wait
    に似てますが
    に似てますが
    に似てますが
    に似てますが
    に似てますが
    に似てますが
    implicitly wait
    implicitly wait
    implicitly wait
    implicitly wait
    implicitly wait
    implicitly wait
    が要素の表示待ちにのみ適用されるのに対し
    が要素の表示待ちにのみ適用されるのに対し
    が要素の表示待ちにのみ適用されるのに対し
    が要素の表示待ちにのみ適用されるのに対し
    が要素の表示待ちにのみ適用されるのに対し
    が要素の表示待ちにのみ適用されるのに対し
    こちらはアサーション含め全アクションにも適用されます
    こちらはアサーション含め全アクションにも適用されます
    こちらはアサーション含め全アクションにも適用されます
    こちらはアサーション含め全アクションにも適用されます
    こちらはアサーション含め全アクションにも適用されます
    こちらはアサーション含め全アクションにも適用されます
    65 / 72

    View Slide

  66. インストールは超簡単
    インストールは超簡単
    インストールは超簡単
    インストールは超簡単
    インストールは超簡単
    インストールは超簡単
    codecept.conf.js
    codecept.conf.js
    codecept.conf.js
    codecept.conf.js
    codecept.conf.js
    codecept.conf.js
    に以下を追記
    に以下を追記
    に以下を追記
    に以下を追記
    に以下を追記
    に以下を追記
    plugins
    plugins:
    : {
    {
    retryFailedStep
    retryFailedStep:
    : {
    {
    enabled
    enabled:
    : true
    true,
    ,
    }
    },
    ,
    }
    },
    ,
    66 / 72

    View Slide

  67. 改めて実行してみます
    改めて実行してみます
    改めて実行してみます
    改めて実行してみます
    改めて実行してみます
    改めて実行してみます
    $ npx codeceptjs run github2_test.js
    $ npx codeceptjs run github2_test.js
    Github --
    Github --
    Can Sign Up
    Can Sign Up
    I am on page "https://github.com"
    I am on page "https://github.com"
    I fill field "Username", "tsuemura"
    I fill field "Username", "tsuemura"
    I see "Something went wrong"
    I see "Something went wrong"
    ✔ OK in 4039ms
    ✔ OK in 4039ms
    今度は成功!
    今度は成功!
    今度は成功!
    今度は成功!
    今度は成功!
    今度は成功!
    67 / 72

    View Slide

  68. 設定ファイルにたった5
    行追加するだけで
    設定ファイルにたった5
    行追加するだけで
    設定ファイルにたった5
    行追加するだけで
    設定ファイルにたった5
    行追加するだけで
    設定ファイルにたった5
    行追加するだけで
    設定ファイルにたった5
    行追加するだけで
    テストコードが
    テストコードが
    テストコードが
    テストコードが
    テストコードが
    テストコードが
    SPA
    対応になってしまいました!!!!
    SPA
    対応になってしまいました!!!!
    SPA
    対応になってしまいました!!!!
    SPA
    対応になってしまいました!!!!
    SPA
    対応になってしまいました!!!!
    SPA
    対応になってしまいました!!!!
    68 / 72

    View Slide

  69. おわかりいただけただろうか……
    おわかりいただけただろうか……
    おわかりいただけただろうか……
    おわかりいただけただろうか……
    おわかりいただけただろうか……
    おわかりいただけただろうか……
    (CodeceptJS
    の便利さを)
    (CodeceptJS
    の便利さを)
    (CodeceptJS
    の便利さを)
    (CodeceptJS
    の便利さを)
    (CodeceptJS
    の便利さを)
    (CodeceptJS
    の便利さを)
    69 / 72

    View Slide

  70. 他にもいろんな機能が盛り沢山
    他にもいろんな機能が盛り沢山
    他にもいろんな機能が盛り沢山
    他にもいろんな機能が盛り沢山
    他にもいろんな機能が盛り沢山
    他にもいろんな機能が盛り沢山
    ビジュアルテスト(画像比較)
    ビジュアルテスト(画像比較)
    ビジュアルテスト(画像比較)
    ビジュアルテスト(画像比較)
    ビジュアルテスト(画像比較)
    ビジュアルテスト(画像比較)
    テスト失敗時に自動でスクリーンショット撮影
    テスト失敗時に自動でスクリーンショット撮影
    テスト失敗時に自動でスクリーンショット撮影
    テスト失敗時に自動でスクリーンショット撮影
    テスト失敗時に自動でスクリーンショット撮影
    テスト失敗時に自動でスクリーンショット撮影
    Allure Reporter
    によるキレイなレポート
    Allure Reporter
    によるキレイなレポート
    Allure Reporter
    によるキレイなレポート
    Allure Reporter
    によるキレイなレポート
    Allure Reporter
    によるキレイなレポート
    Allure Reporter
    によるキレイなレポート
    テストコードとレポートの翻訳
    テストコードとレポートの翻訳
    テストコードとレポートの翻訳
    テストコードとレポートの翻訳
    テストコードとレポートの翻訳
    テストコードとレポートの翻訳
    Appium
    によるネイティブアプリのテスト
    Appium
    によるネイティブアプリのテスト
    Appium
    によるネイティブアプリのテスト
    Appium
    によるネイティブアプリのテスト
    Appium
    によるネイティブアプリのテスト
    Appium
    によるネイティブアプリのテスト
    BDD(Gherkin)
    記法のサポート
    BDD(Gherkin)
    記法のサポート
    BDD(Gherkin)
    記法のサポート
    BDD(Gherkin)
    記法のサポート
    BDD(Gherkin)
    記法のサポート
    BDD(Gherkin)
    記法のサポート
    ...etc
    ...etc
    ...etc
    ...etc
    ...etc
    ...etc




































    70 / 72

    View Slide

  71. 質問等あれば遠慮なくどうぞ!
    質問等あれば遠慮なくどうぞ!
    質問等あれば遠慮なくどうぞ!
    質問等あれば遠慮なくどうぞ!
    質問等あれば遠慮なくどうぞ!
    質問等あれば遠慮なくどうぞ!
    Twitter: @tsueeemura
    Twitter: @tsueeemura
    Twitter: @tsueeemura
    Twitter: @tsueeemura
    Twitter: @tsueeemura
    Twitter: @tsueeemura
    Teratail: @tsuemura
    Teratail: @tsuemura
    Teratail: @tsuemura
    Teratail: @tsuemura
    Teratail: @tsuemura
    Teratail: @tsuemura
    71 / 72

    View Slide

  72. おわり
    おわり
    おわり
    おわり
    おわり
    おわり
    72 / 72

    View Slide