Save 37% off PRO during our Black Friday Sale! »

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

44b799f91cc48e38c5fe9f5d9c5ecc61?s=47 Takaichi00
October 16, 2020

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

44b799f91cc48e38c5fe9f5d9c5ecc61?s=128

Takaichi00

October 16, 2020
Tweet

Transcript

  1. Selenide + Cucumber で実現する UI テスト自動化 + BDD #jjug #jjug_ccc

    髙市 智章 (Tomoaki Takaichi) Nov, 7, 2020 JJUG CCC 2020 Fall
  2. 自己紹介 @Takaichi00 tomoaki.takaichi.5 ・髙市 智章(タカイチ トモアキ) ・Java / Node でのシステム開発

    ・CI / CD ・Container / k8s ・アジャイル開発実践 共著: クリーンなコードへの SonarQube即効活用術 http://u0u0.net/RSvx
  3. ❏ Selenide と Cucumber の概要を知る ❏ Selenide と Cucumber を使った開発イメージを掴む

    ❏ テストを運用するときの Tips ❏ 1シナリオを実装するデモ 本日お話すること
  4. Selenide のご紹介

  5. ❏ Selenideは、Selenium WebDriver(後述) を利用した UI / 受け入れテスト自動化のためのフレームワーク ❏ 自動 UI

    テスト実装の際、 Selenium WebDriver では冗長な 記述になりがちだった処理を Selenide はラッピングしてい る。よってよりビジネスロジックに集中したテストを実装で きるということを特徴としている ❏ Java 言語でのみ記述できる Selenide 概要
  6. ❏ Selenium WebDriver とは、ブラウザ操作を自動化する ツール ❏ ThoughtWorks 社によって開発され、UI テスト自動化や Web

    サイトのクローリングにも利用される ❏ Java 言語以外でも記述することができる Selenium WebDriver 概要
  7. ❏ Selenide は Selenium をラッパーするアーキテクチャと なっている Selenide の動作概要 出典: https://hackr.io/blog/what-is-selenium-webdriver/thumbnail/large

    Wrapper
  8. ❏ Selenium は WebDriver を直接操作するため、低レイヤーで詳 細な操作を実行することができる ❏ しかし単にブラウザテストをするには冗長な記述をしないといけない ことも ❏

    Selenide ではより UI と受け入れテストを実装しやすいように 設計されている ❏ WebDriver を直接操作することなく実装できる ❏ Selenium と比較してコンパクトにテスト実装が可能 Selenium と Selenide の比較
  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");
  10. ❏ Ajax 処理の結果をアサーションするときの違い (https://github.com/selenide/selenide/wiki/Selenide-vs-Selenium) Selenium と Selenide の比較 Selenium FluentWait<By>

    fluentWait = new FluentWait<By>(By.tagName("TEXTAREA")); fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS); fluentWait.withTimeout(1000, TimeUnit.MILLISECONDS); fluentWait.until(new Predicate<By>() { 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"));
  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 がダウンロードされる ❏ バイナリをバージョン管理しなくてよくなる
  12. ブラウザでページを開く Selenide を使った UI テストのサンプル id が “header” の文字列 をアサーションする

    id が “search-bar” のフィー ルドにテキストを入力する ❏ jQuery のような記述で要素を取得したり、アサーション をすることが可能
  13. 要素をクリックする Selenide を使った UI テストのサンプル ❏ 画面をクリックする、スクロールするなどの挙動も表現できる 要素までスクロールする ドラックアンドドロップする この他にも様々なことができるので実装の際は公式ドキュメントをご参考に!

    (https://selenide.org/documentation.html)
  14. ❏ 例えば複数のテストケースから <h1> タグのタイトルをアサー ションしていた場合、<h1> タグから <h2> に変えただけで複 数のテストケースを修正しないといけないためメンテナンスが 大変になる

    Page Object パターン <h1>hoge<h1> $(“h1”).shouldHave(“...”) $(“h1”).hover(“...”) $(“h1”)..shouldNotBe(“...”) <h2>hoge<h2> $(“h2”).shouldHave(“...”) $(“h2”).hover(“...”) $(“h2”)..shouldNotBe(“...”) .html テストケース ... .html ... テストケース
  15. ❏ テストケースでは Page Object を参照するようにし、Page Object が <h1> などの要素を取得するようにすれば、<h2> に変わっても

    Page Object だけを変更するだけでテストケースを修正せずに済む Page Object パターン <h1>hoge<h1> getHeading.shouldHave(“...”) getHeading.hover(“...”) getHeading.shouldNotBe(“...”) public SelenideElement getHeading() { return $(“h1”); → return $(“h2”); } <h2>hoge<h2> .html Page Object テストケース ...
  16. Selenide のデモ

  17. Cucumber のご紹介

  18. ❏ Gherkin 記法を用いてテストケースを記述し、実行できる ツール ❏ ビジネスサイドとのギャップを埋めたり、 BDD をサポー トするツールと銘打っている ❏

    自然言語を用いてテストケースを記載できるという点が一 番の特徴 ❏ 日本語でテストケースを書くことも可能 Cucumber の概要
  19. ❏ feature ファイルにテストケースを記述し、steps ファイ ルにそのテストを実装する Cucumber の構成要素 feature ファイル steps

    ファイル
  20. ❏ Gherkin 記法の概要は以下 Gherkin 記法 参考: https://blog.eiel.info/blog/2013/02/12/gherkin/ 使用するキーワードの言語を指定 タグは機能やシナリオに指定可能 背景ではシナリオの前に実行したいステップを定義

    できる ステップは 前提/もし/ならば/かつ/ などがある シナリオはテストケースを表し、ステップを複数持つ 機能ではこのファイルが表す機能名を記載する
  21. ❏ Data Table… テーブルなど複雑なデータ構造を表したい 場合に利用する ❏ Scenario Outline… いつくかの違う値で同じシナリオを テストしたい場合に利用する

    Data Table と Scenario Outline Data Table Scenario Outline
  22. ❏ Cucumber で Java のテストを実装するには ”io.cucumber” の “cucumber-java” と “cucumber-junit”

    を依存関係に追加する ❏ JUnit5 はまだ対応していないらしく、Junit5 のテストと 共存させるには “junit-vintage-engine” の依存を追加す る必要がある (https://github.com/cucumber/cucumber-jvm/issues/1149) Cucumber のセットアップ
  23. ❏ steps ファイルに Selenide を用いた画面テストを実装する Selenide + Cucumber でテストを実装する steps

    ファイル
  24. Selenide + Cucumber のデモ

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

  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 ファイ ルの乱立
  27. ❏ かつては Cucumber のテストは “.story” が使われていた ❏ しかし例えばユーザーストーリー単位でシナリオを書いた場合、開発 が進むにつれて以前のストーリーと矛盾するといったことが発生する ❏

    ドキュメントとして機能しなくなってしまう ❏ 1つのユーザーストーリーでも複数の機能に変更がかかる場合はストー リーとフィーチャーを 1対1 で作成するのは難しい ❏ よって機能 (feature) ごとにファイルを分けるように変更された なぜ .story ではなく .feature なのか
  28. ❏ 「BDD とは、ステークホルダーの視点に立って振る舞いを説明するこ とにより、アプリケーションを実装するための手法」(The RSpec Book p121) ❏ BDD のプロセスは外側のループ

    (Cucumber によるシナリオテスト /ATDD) と内側のループ (JUnit などで実装するユニットテスト/TDD) から構成される BDD (Behavior Driven Development) 出典: https://i.stack.imgur.com/i9Uej.png
  29. ❏ Cucumber + Selenide を使うことで、画面があるシステ ムを「失敗する受け入れテスト」→ 「TDD」 →「受け入 れテスト成功」の開発サイクルを実現できる BDD

    のサイクル例 (CSD, 実践テスト駆動) スプリント バックログ 失敗する受け入れテスト を実装 (Cucumber) 受け入れテストが通るよ うに内側の機能の実装 (TDD / Unit Test) 受け入れテスト成功 (Cucumber) レビュー ...
  30. BDD サイクルのデモ

  31. デモプロジェクト概要 ❏ 図書管理システムを作成する ❏ 図書の情報を DB に保存し、本の一覧確認/貸出/返却 など をシステムでできるようにしたい ❏

    現在は管理している本のタイトルだけが表示できるように なっている Spring Boot Thymeleaf DB
  32. ❏ 顧客の方と一緒に .feature ファイルを作成する ❏ 失敗する Cucumber の受け入れテストを実装する ❏ DB

    取得処理をモックにして画面とController の実装をする ❏ DB 取得処理を実装する ❏ 今回は Spring JPA を利用するためスキップ ❏ Cucumber の受け入れテストが成功する デモ概要
  33. ❏ BDD ではエンドユーザ要件を扱う受け入れテストを自動化し、そ のテストを通すことを目標として開発を進める ❏ 後続の実装がないところはモックオブジェクトを作成することで実 装を始めることができる 創発的設計 UserInterface 実装を進める流れ

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

  35. ❏ BDD では実際のユーザーの要件に近いところから開発を進 めることで、事前にすべてを設計する必要がなくなり、不 必要なものを作るというリスクを減らすことができる ❏ → Big Design Up

    Front (BDUF) を避ける 創発的設計 「最初からすべてを理解するのではなく、要件対する議論と理解を 目の前の要件に絞り、見えている要件を単位として外側の界面から ソフトウェアの内側に向かって必要最低限の範囲で開発を進められ るようになったのです(ウォーキングスケルトン)」 (テスト駆動開発 付録C p.292 より)
  36. まとめ

  37. ❏ Selenide は Java 言語で画面自動テストを実装できる ❏ Cucumber は自然言語でテストケースを記述できる ❏ ビジネス側との協働

    ❏ Selenide + Cucumber を組み合わせた自動テスト ❏ BDD の実現 ❏ 創発的設計の実現 まとめ
  38. ご清聴ありがとうございました

  39. ❏ 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 参考文献