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

【JJUG CCC 2020 Fall】Selenide + Cucumber で実現する UI テスト自動化 + BDD

Takaichi00
October 16, 2020

【JJUG CCC 2020 Fall】Selenide + Cucumber で実現する UI テスト自動化 + BDD

Takaichi00

October 16, 2020
Tweet

More Decks by Takaichi00

Other Decks in Technology

Transcript

  1. Selenide + Cucumber で実現する UI テスト自動化 + BDD
    #jjug #jjug_ccc
    髙市 智章 (Tomoaki Takaichi)
    Nov, 7, 2020 JJUG CCC 2020 Fall

    View full-size slide

  2. 自己紹介
    @Takaichi00
    tomoaki.takaichi.5
    ・髙市 智章(タカイチ トモアキ)
    ・Java / Node でのシステム開発
    ・CI / CD
    ・Container / k8s
    ・アジャイル開発実践
    共著: クリーンなコードへの
    SonarQube即効活用術
    http://u0u0.net/RSvx

    View full-size slide

  3. ❏ Selenide と Cucumber の概要を知る
    ❏ Selenide と Cucumber を使った開発イメージを掴む
    ❏ テストを運用するときの Tips
    ❏ 1シナリオを実装するデモ
    本日お話すること

    View full-size slide

  4. Selenide のご紹介

    View full-size slide

  5. ❏ Selenideは、Selenium WebDriver(後述) を利用した UI
    / 受け入れテスト自動化のためのフレームワーク
    ❏ 自動 UI テスト実装の際、 Selenium WebDriver では冗長な
    記述になりがちだった処理を Selenide はラッピングしてい
    る。よってよりビジネスロジックに集中したテストを実装で
    きるということを特徴としている
    ❏ Java 言語でのみ記述できる
    Selenide 概要

    View full-size slide

  6. ❏ Selenium WebDriver とは、ブラウザ操作を自動化する
    ツール
    ❏ ThoughtWorks 社によって開発され、UI テスト自動化や
    Web サイトのクローリングにも利用される
    ❏ Java 言語以外でも記述することができる
    Selenium WebDriver 概要

    View full-size slide

  7. ❏ Selenide は Selenium をラッパーするアーキテクチャと
    なっている
    Selenide の動作概要
    出典: https://hackr.io/blog/what-is-selenium-webdriver/thumbnail/large
    Wrapper

    View full-size slide

  8. ❏ Selenium は WebDriver を直接操作するため、低レイヤーで詳
    細な操作を実行することができる
    ❏ しかし単にブラウザテストをするには冗長な記述をしないといけない
    ことも
    ❏ Selenide ではより UI と受け入れテストを実装しやすいように
    設計されている
    ❏ WebDriver を直接操作することなく実装できる
    ❏ Selenium と比較してコンパクトにテスト実装が可能
    Selenium と Selenide の比較

    View full-size slide

  9. ❏ ブラウザを開く処理の違い
    (https://github.com/selenide/selenide/wiki/Selenide-vs-Selenium)
    Selenium と Selenide の比較
    Selenium
    DesiredCapabilities desiredCapabilities = DesiredCapabilities.htmlUnit();
    desiredCapabilities.setCapability(HtmlUnitDriver.INVALIDSELECTIONERROR, true);
    desiredCapabilities.setCapability(HtmlUnitDriver.INVALIDXPATHERROR, false);
    desiredCapabilities.setJavascriptEnabled(true);
    WebDriver driver = new HtmlUnitDriver(desiredCapabilities);
    Selenide
    open("/my-application/login");

    View full-size slide

  10. ❏ Ajax 処理の結果をアサーションするときの違い
    (https://github.com/selenide/selenide/wiki/Selenide-vs-Selenium)
    Selenium と Selenide の比較
    Selenium
    FluentWait fluentWait = new FluentWait(By.tagName("TEXTAREA"));
    fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS);
    fluentWait.withTimeout(1000, TimeUnit.MILLISECONDS);
    fluentWait.until(new Predicate() {
    public boolean apply(By by) {
    try {
    return browser.findElement(by).isDisplayed();
    } catch (NoSuchElementException ex) {
    return false;
    }
    }
    });
    assertEquals("John", browser.findElement(By.tagName("TEXTAREA")).getAttribute("value"));
    Selenide
    $("TEXTAREA").shouldHave(value("John"));

    View full-size slide

  11. Selenide のセットアップ
    ❏ 依存関係に “com.codeborne.selenide” を追加する
    ❏ ブラウザを操作するために必要な WebDriver をダウン
    ロードする (http://chromedriver.storage.googleapis.com/index.html)
    ❏ 手動でダウンロードするか、”webdriverextensions-maven-plugin” を利用
    することで自動でダウンロードしてくれる
    (https://su-kun1899.hatenablog.com/entry/2017/11/14/220000)
    ❏ “mvn generate-sources” コマンドで${basedir}/drivers に
    WebDriver がダウンロードされる
    ❏ バイナリをバージョン管理しなくてよくなる

    View full-size slide

  12. ブラウザでページを開く
    Selenide を使った UI テストのサンプル
    id が “header” の文字列
    をアサーションする
    id が “search-bar” のフィー
    ルドにテキストを入力する
    ❏ jQuery のような記述で要素を取得したり、アサーション
    をすることが可能

    View full-size slide

  13. 要素をクリックする
    Selenide を使った UI テストのサンプル
    ❏ 画面をクリックする、スクロールするなどの挙動も表現できる
    要素までスクロールする
    ドラックアンドドロップする
    この他にも様々なことができるので実装の際は公式ドキュメントをご参考に!
    (https://selenide.org/documentation.html)

    View full-size slide

  14. ❏ 例えば複数のテストケースから タグのタイトルをアサー
    ションしていた場合、 タグから に変えただけで複
    数のテストケースを修正しないといけないためメンテナンスが
    大変になる
    Page Object パターン
    hoge
    $(“h1”).shouldHave(“...”)
    $(“h1”).hover(“...”)
    $(“h1”)..shouldNotBe(“...”)
    hoge
    $(“h2”).shouldHave(“...”)
    $(“h2”).hover(“...”)
    $(“h2”)..shouldNotBe(“...”)
    .html
    テストケース
    ...
    .html
    ...
    テストケース

    View full-size slide

  15. ❏ テストケースでは Page Object を参照するようにし、Page Object
    が などの要素を取得するようにすれば、 に変わっても
    Page Object だけを変更するだけでテストケースを修正せずに済む
    Page Object パターン
    hoge
    getHeading.shouldHave(“...”)
    getHeading.hover(“...”)
    getHeading.shouldNotBe(“...”)
    public SelenideElement getHeading() {
    return $(“h1”); → return $(“h2”);
    }
    hoge
    .html
    Page Object
    テストケース
    ...

    View full-size slide

  16. Selenide のデモ

    View full-size slide

  17. Cucumber のご紹介

    View full-size slide

  18. ❏ Gherkin 記法を用いてテストケースを記述し、実行できる
    ツール
    ❏ ビジネスサイドとのギャップを埋めたり、 BDD をサポー
    トするツールと銘打っている
    ❏ 自然言語を用いてテストケースを記載できるという点が一
    番の特徴
    ❏ 日本語でテストケースを書くことも可能
    Cucumber の概要

    View full-size slide

  19. ❏ feature ファイルにテストケースを記述し、steps ファイ
    ルにそのテストを実装する
    Cucumber の構成要素
    feature ファイル steps ファイル

    View full-size slide

  20. ❏ Gherkin 記法の概要は以下
    Gherkin 記法
    参考: https://blog.eiel.info/blog/2013/02/12/gherkin/
    使用するキーワードの言語を指定
    タグは機能やシナリオに指定可能
    背景ではシナリオの前に実行したいステップを定義
    できる
    ステップは 前提/もし/ならば/かつ/ などがある
    シナリオはテストケースを表し、ステップを複数持つ
    機能ではこのファイルが表す機能名を記載する

    View full-size slide

  21. ❏ Data Table… テーブルなど複雑なデータ構造を表したい
    場合に利用する
    ❏ Scenario Outline… いつくかの違う値で同じシナリオを
    テストしたい場合に利用する
    Data Table と Scenario Outline
    Data Table Scenario Outline

    View full-size slide

  22. ❏ Cucumber で Java のテストを実装するには
    ”io.cucumber” の “cucumber-java” と
    “cucumber-junit” を依存関係に追加する
    ❏ JUnit5 はまだ対応していないらしく、Junit5 のテストと
    共存させるには “junit-vintage-engine” の依存を追加す
    る必要がある
    (https://github.com/cucumber/cucumber-jvm/issues/1149)
    Cucumber のセットアップ

    View full-size slide

  23. ❏ steps ファイルに Selenide を用いた画面テストを実装する
    Selenide + Cucumber でテストを実装する
    steps ファイル

    View full-size slide

  24. Selenide + Cucumber のデモ

    View full-size slide

  25. シナリオテスト実装の Tips

    View full-size slide

  26. ❏ feature ファイルと steps ファイルを 1対1 で対応させるのは直感的
    だがアンチパターンとされている
    ❏ シナリオ間で steps の共有ができないため、似たような処理をする
    steps ファイルが乱立してしまう
    ❏ feature ごとに steps ファイルを作成するのではなく、ドメインの単
    位で作成することが推奨されている
    Cucumber アンチパターン
    .feature A
    .feature B
    .feature C
    steps A
    steps B
    steps C
    .feature A
    .feature B
    .feature C
    Domain A
    steps
    Domain B
    steps
    step ファイ
    ルの乱立

    View full-size slide

  27. ❏ かつては Cucumber のテストは “.story” が使われていた
    ❏ しかし例えばユーザーストーリー単位でシナリオを書いた場合、開発
    が進むにつれて以前のストーリーと矛盾するといったことが発生する
    ❏ ドキュメントとして機能しなくなってしまう
    ❏ 1つのユーザーストーリーでも複数の機能に変更がかかる場合はストー
    リーとフィーチャーを 1対1 で作成するのは難しい
    ❏ よって機能 (feature) ごとにファイルを分けるように変更された
    なぜ .story ではなく .feature なのか

    View full-size slide

  28. ❏ 「BDD とは、ステークホルダーの視点に立って振る舞いを説明するこ
    とにより、アプリケーションを実装するための手法」(The RSpec
    Book p121)
    ❏ BDD のプロセスは外側のループ (Cucumber によるシナリオテスト
    /ATDD) と内側のループ (JUnit などで実装するユニットテスト/TDD)
    から構成される
    BDD (Behavior Driven Development)
    出典: https://i.stack.imgur.com/i9Uej.png

    View full-size slide

  29. ❏ Cucumber + Selenide を使うことで、画面があるシステ
    ムを「失敗する受け入れテスト」→ 「TDD」 →「受け入
    れテスト成功」の開発サイクルを実現できる
    BDD のサイクル例 (CSD, 実践テスト駆動)
    スプリント
    バックログ
    失敗する受け入れテスト
    を実装 (Cucumber)
    受け入れテストが通るよ
    うに内側の機能の実装
    (TDD / Unit Test)
    受け入れテスト成功
    (Cucumber)
    レビュー
    ...

    View full-size slide

  30. BDD サイクルのデモ

    View full-size slide

  31. デモプロジェクト概要
    ❏ 図書管理システムを作成する
    ❏ 図書の情報を DB に保存し、本の一覧確認/貸出/返却 など
    をシステムでできるようにしたい
    ❏ 現在は管理している本のタイトルだけが表示できるように
    なっている
    Spring Boot
    Thymeleaf DB

    View full-size slide

  32. ❏ 顧客の方と一緒に .feature ファイルを作成する
    ❏ 失敗する Cucumber の受け入れテストを実装する
    ❏ DB 取得処理をモックにして画面とController の実装をする
    ❏ DB 取得処理を実装する
    ❏ 今回は Spring JPA を利用するためスキップ
    ❏ Cucumber の受け入れテストが成功する
    デモ概要

    View full-size slide

  33. ❏ BDD ではエンドユーザ要件を扱う受け入れテストを自動化し、そ
    のテストを通すことを目標として開発を進める
    ❏ 後続の実装がないところはモックオブジェクトを作成することで実
    装を始めることができる
    創発的設計
    UserInterface
    実装を進める流れ

    View full-size slide

  34. ❏ テーブル設計や IF の設計を事前に行うと、不必要なもの
    を作るリスクや、機能を作り終わってから設計に不備があ
    ることに気づくため手戻りコストのリスクが高い
    創発的設計
    実装を進める流れ
    UserInterface

    View full-size slide

  35. ❏ BDD では実際のユーザーの要件に近いところから開発を進
    めることで、事前にすべてを設計する必要がなくなり、不
    必要なものを作るというリスクを減らすことができる
    ❏ → Big Design Up Front (BDUF) を避ける
    創発的設計
    「最初からすべてを理解するのではなく、要件対する議論と理解を
    目の前の要件に絞り、見えている要件を単位として外側の界面から
    ソフトウェアの内側に向かって必要最低限の範囲で開発を進められ
    るようになったのです(ウォーキングスケルトン)」
    (テスト駆動開発 付録C p.292 より)

    View full-size slide

  36. ❏ Selenide は Java 言語で画面自動テストを実装できる
    ❏ Cucumber は自然言語でテストケースを記述できる
    ❏ ビジネス側との協働
    ❏ Selenide + Cucumber を組み合わせた自動テスト
    ❏ BDD の実現
    ❏ 創発的設計の実現
    まとめ

    View full-size slide

  37. ご清聴ありがとうございました

    View full-size slide

  38. ❏ Kent Beck (2017) 『テスト駆動開発』 (和田 卓人 訳) オーム社
    ❏ Steve Freeman, Nat Pryce (2012) 『実践テスト駆動開発』 (和智 右桂、 高木 正弘 訳) 翔泳社
    ❏ サンプルコード (https://github.com/Takaichi00/selenide-cucumber-sample)
    ❏ Selenide入門
    ❏ Selenideノウハウ
    ❏ Selenide~Javaで超簡単・簡潔にUIテストを書く~
    ❏ Selenideを活用したい人に向けて
    ❏ Javaで簡単にUIテストを書けるSelenideを使おう~Selenideの概要とテストの保守性を上げるPage
    Objectパターンの紹介
    ❏ MavenでWebDriverの管理にはwebdriverextensionsが便利そう
    ❏ Cucumber のフィーチャの文法 - Gherkin
    ❏ Page Object Patternで保守性の高いUIテストコードを書こう!【Selenide】
    ❏ Anti-patterns (Cucumber official)
    ❏ Selenide vs Selenium
    ❏ Selenide Java Library:簡単なことは簡単に,Web UI テスト自動化の敷居を下げ,生産性をあげる
    魔法の Wrapper
    ❏ オープンソースの自動テストツール/Selenideとは
    ❏ Cucumber Hooks
    参考文献

    View full-size slide