Successfully reported this slideshow.
Your SlideShare is downloading. ×

テスト自動化の様々な道具を使ってみた四方山話

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 55 Ad

More Related Content

Slideshows for you (20)

Advertisement

Similar to テスト自動化の様々な道具を使ってみた四方山話 (20)

Recently uploaded (20)

Advertisement

テスト自動化の様々な道具を使ってみた四方山話

  1. 1. テスト自動化の様々 な道具を使ってみた 四方山話 Selenium Webdriver, fuluentlenium, geb, gebspec
  2. 2. 自己紹介 twitter: @haljik もうすぐフリーのプログラマーです。 JVM言語や、Java周りのエコシステムが好きで す。 関西Javaエンジニアの会,Devlove関西,京都アジ ャイル勉強会とかちらほらと参加
  3. 3. 今日紹介するツール 4 Selenium Webdriver 4 Fluentlenium 4 Geb/GebSpec
  4. 4. 全部WEBブラウザ の操作を自動化する ツールですが
  5. 5. どれも出来ることは 変わらない
  6. 6. 違いは書きやすさと 表現力
  7. 7. ということでそれぞ れ書くと
  8. 8. Selenium WebDriver 一番低レベルな実装でこれでできない操作は他の でもできない public class BingTest {//ドライバーのセットアップとかは省略 @Test public void title_of_bing_should_contain_search_query_name() throws Exception { driver.get("http://www.bing.com"); driver.findElement(By.id("sb_form_q")).sendKeys("automation"); driver.findElement(By.id("sb_form_go")).click(); assertThat(driver.getTitle(), containsString("automation")); } } (´・ω・`)
  9. 9. Fluentlenium Javaで書ける範囲で頑張ったAPI。WebDriver のラッパー public class BingTest extends FluentTest { @Test public void title_of_bing_should_contain_search_query_name() { goTo("http://www.bing.com"); fill("#sb_form_q").with("automation"); submit("#sb_form_go"); assertThat(title()).contains("automation"); } } (`・ω・´)
  10. 10. Geb (「じぇぶ」と読む) Groovyで書ける。Spockで書ける。 WebDriver のラッパー class BingSpec extends GebSpec { def "title_of_bing_should_contain_search_query_name"() { when: go "http://www.bing.com" $("#sb_form_q").value "automation" $("#sb_form_go").click() then: title.contains("automation") } } (・ ・)イイ!! ※但しIDEAに限る…
  11. 11.
  12. 12. 実際の開発で使って みた話
  13. 13. Context 4 大規模エンタープライズプロジェクト向けの WEBアプリケーションフレームワーク 4 言語はJava やりたいこと 4 いつまでもリファクタリングし続けたい 4 要望へスピーディーに対応してリリースしたい
  14. 14. でも大規模プロジェクトの 基盤って 4 一旦リリースした後の変更は膨大なテストをパ スさせないかぎり無理 4 基本的に嫌がられる
  15. 15. でも変更し続けたい
  16. 16. どうしよう
  17. 17. 前例を作ろう
  18. 18. 膨大なテストを自動 化し、リリース実績 を積んでゴリ押しす る感じでやってみま した
  19. 19. テスト構成 4 ユニットテスト&コンポーネントテスト Junitで個々のコンポーネントをテスト 4 結合テスト Junit&Fluentleniumを使った機能別マルチ ブラウザテスト 4 総合テスト Junit&Fluentleniumを使ったブラウザテス トで実業務アプリを模したアプリのシナリオテ スト
  20. 20. さらにこれらを Jenkinsで常時実行 する
  21. 21. ブラウザテストを常 時実行する環境って
  22. 22. Selenium Grid vs Jenkins Slave
  23. 23. Selenium Grid
  24. 24. Selenium Gridの構成
  25. 25. メリット 4 消費するクライアントリソースが少ない 4 テストが速い デメリット 4 ブラウザ実行ホストのアドレスをサーバが知っ ている必要がある 4 ブラウザ実行ホストにサーバを常駐させる必要 がある
  26. 26. Jenkins Slave
  27. 27. Jenkins Slaveの構成
  28. 28. メリット 4 CIサーバはブラウザ実行ホストのアドレスを知 らなくても良い 4 WebBrowser実行ホスト側にサーバをセット アップしなくて良い デメリット 4 JenkinsのJobそのものを実行するため消費リ ソースが多い
  29. 29. 構成の簡単さで今回 はJenkins Slaveを選 択
  30. 30. いざテストを始める と
  31. 31. テストが不安定
  32. 32. 原因 1. CIサーバとWebBrowser実行ホスト間のネッ トワーク 2. WebBrowser実行ホストの物理的故障 3. タイミングに依存したテスト
  33. 33. 1. CIサーバ、WebBrowser実行ホス ト間のネットワーク 4 ネットワークが切れやすくテストが失敗する connection resetが頻発とか 4 ネットワークが遅すぎてテストが失敗する time outとか
  34. 34. 2. WebBrowser実行ホストの物理 的故障 4 電源周りとか壊れやすい 4 クライアントマシン(PC)は常時可動するよう に作られていない
  35. 35. 1.と2.の解決策
  36. 36. 仮想化 ネットワーク的に近い場所でJenkins Slaveや、 Seleniumサーバ複数を常時起動させられるため、 仮想化するのが理想 4 課題 WindowsやLinuxは簡単に仮想化できるが… Mac/IOSは…
  37. 37. 3. タイミングに依存したテスト 4 Thread.sleep()を使っている 1. シンプルに作ったテストケースで何故か失 敗する場所をThread.sleep()を入れてごま かす 2. 成功したり失敗したりで安定しない 3. sleepする量や場所を増やす 4. 2と3を繰り返すも安定しないうえに、ひた すら遅いテストになる
  38. 38. 本当の原因 DOM構造の変わらない画面操作
  39. 39. 例 4 一覧表のページング 4 Ajaxによる値の書き換え
  40. 40. 解決策 アサートの成功を待つ
  41. 41. アサートの成功を待つ 4 何らかの画面操作の後は必ず何らかの値のアサ ートを行っている 4 DOMの構造が変わらなくてもアサート対象の 値は変わっている なので…
  42. 42. 値が期待する値に変 わるのをタイムアウ ト値を指定して待ち タイムアウトしたら AssertionErrorとみ なす!
  43. 43. どーやって待つのか
  44. 44. Selenium WebDriverの場合 driver.findElement(By.id("updateButton")).click() new WebDriverWait(driver, 3).until( ExpectedConditions .textToBePresentInElementLocated(By.id("message"), "更新しました") ); Timeout時のメッセージ org.openqa.selenium.TimeoutException:Timed out after 3 seconds waiting for text ('更新しました') to be present in element found by By.id: message 思ったより良い感じ
  45. 45. Fluentleniumの場合 click("#updateButton"); await().atMost(3, TimeUnit.SECONDS).until("#message").hasText("更新しました"); Timeout時のメッセージ org.openqa.selenium.TimeoutException: Timed out after 3 seconds: Selector #message has not the text 更新しました. やっぱりこっちのが良い
  46. 46. Gebの場合 $("#updateButton").click(); waitFor(3) { assert $("#message").text() == "更新しました" } Timeout時のメッセージ assert $("#message").text() == "更新しました" | | | | "" false [[[[[FirefoxDriver: firefox on MAC (ry PowerAssertすごい ※但しIDEAに限る ※PowerAssertはGebというよりSpockの特徴
  47. 47. こんな感じでやって みて大体のテストは 安定し、現時点では 1日でリリースがで きるようになった
  48. 48. 残る問題 1. 画面のテストは変更がめんどくさい 2. ファイルアップロードの自動化
  49. 49. 1. 変更が面倒
  50. 50. Page Object Pattern で画面と対になる Page Objectに画面構 造を隠 し、テスト を守る
  51. 51. 2. ファイルアップロ ード…
  52. 52. 最近のブラウザはセ キュリティが厳しく てプログラムからフ ァイル指定させてく れない
  53. 53. ファイルアップロードの解決 策の候補たち 4 Wsh (Windowsでは定番っぽい?) 4 Sikuli (安定を望む) 4 java.awt.Robotで座標指定クリック (...なつ かしい) 4 アプリ側をHTML5のFileAPIとAjaxで実装す る (IEが…) ※試せていません…
  54. 54. 現状決定打になるも のがないのではと勝 手に思っている
  55. 55. まとめ sleepダメ絶対

×