Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

OSC京都 2015 LT 「テスト自動化の闇と向き合う」

1,309 views

Published on

OSC京都2015のライトニングトーク資料です。

Published in: Technology
  • Be the first to comment

OSC京都 2015 LT 「テスト自動化の闇と向き合う」

  1. 1. テスト自動化の闇と向き合う 新日鉄住金ソリューションズ 石川 真也 (Selenium歴 9ヶ月) Copyright © 2015 NS Solutions Corporation, All rights reserved. 1
  2. 2. ブラウザテスト Copyright © 2015 NS Solutions Corporation, All rights reserved. 2
  3. 3. Copyright © 2015 NS Solutions Corporation, All rights reserved. 3 Internet Explorer 7 Internet Explorer 8 Internet Explorer 9 Internet Explorer 10 Internet Explorer 11 Microsoft Edge Firefox Google Chrome Safari Safari(iOS) Google Chrome(Android) ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 ・アプリにアクセス ・ログイン ・カートに商品を追加 ・配送先を選択 ・支払い方法を選択 ・注文の確認 ・購入完了 自動化したい
  4. 4. テスト自動化 Copyright © 2015 NS Solutions Corporation, All rights reserved. 4
  5. 5. Copyright © 2015 NS Solutions Corporation, All rights reserved. 5 Selenium
  6. 6. Selenium-特徴  OSS(Apache2.0)  様々なブラウザに対応  豊富な言語バインディング  Java, C#, Python, Ruby, JavaScript etc.  豊富な支援ツール  Selenium grid:並列実行  Selenium IDE:画面操作の記録  Appium:iOS, Androidのテスト Microsoft Edgeにも! Copyright © 2015 NS Solutions Corporation, All rights reserved. 6 →間口の広さ
  7. 7. Selenium-コード例 public class Example { public static void main(String[] args) { WebDriver driver = new HtmlUnitDriver(); driver.get("http://www.google.com"); WebElement element = driver.findElement(By.name("q")); element.sendKeys("Cheese!"); element.submit(); System.out.println("Page title is: " + driver.getTitle()); driver.quit(); } } フォーム操作 ページリクエスト 値の取得 Copyright © 2015 NS Solutions Corporation, All rights reserved. 7
  8. 8. テスト自動化の闇 Copyright © 2015 NS Solutions Corporation, All rights reserved. 8
  9. 9. の闇スクリプト保守 Copyright © 2015 NS Solutions Corporation, All rights reserved. 9
  10. 10. Selenium IDEを使えば ブラウザ操作を記録できて便利! Copyright © 2015 NS Solutions Corporation, All rights reserved. 10
  11. 11. どんどんテストスクリプトを 作ろう! Copyright © 2015 NS Solutions Corporation, All rights reserved. 11
  12. 12. driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/Fron driver.findElement(By _id")).clear(); driver.findElement(By _id")).sendKeys("01 driver.findElement(By MenuLogic")).click( assertEquals(" ニュー画面", driver.ge Copyright © 2015 NS Solutions Corporation, All rights reserved. 12
  13. 13. 「ここのフォームの配置 変えといたから」 Copyright © 2015 NS Solutions Corporation, All rights reserved. 13
  14. 14. えっ driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/Fron driver.findElement(By _id")).clear(); driver.findElement(By _id")).sendKeys("01 driver.findElement(By MenuLogic")).click( assertEquals(" ニュー画面", driver.ge Copyright © 2015 NS Solutions Corporation, All rights reserved. 14
  15. 15. Selenium IDEが吐くコードの例 WebElement element = driver.findElement( By.cssSelector("#content > table > tbody > tr:nth-child(4) > td:nth-child(2)“)); ↑Idがcontentの要素の中の ↑table要素の中の ↑tbody要素の中の ↑4番めのtr要素の中の ↑2番めのtd要素 Copyright © 2015 NS Solutions Corporation, All rights reserved. 15 DOM要素の配置が変わると台無し DOMツリー上の位置で操作する要素を特定
  16. 16. えっこれ全部修正ですか? driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); driver.get(baseUrl + "/myVideoRental/Fron driver.findElement(By _id")).clear(); driver.findElement(By _id")).sendKeys("01 driver.findElement(By MenuLogic")).click( assertEquals(" ニュー画面", driver.ge Copyright © 2015 NS Solutions Corporation, All rights reserved. 16
  17. 17. orz Copyright © 2015 NS Solutions Corporation, All rights reserved. 17
  18. 18. スクリプト保守の闇と向き合う • テストを意識した設計 • 要素のクラス、id体系 • テストスクリプトで工夫 • PageObjectパターン • ページごとの操作を抽象化 Copyright © 2015 NS Solutions Corporation, All rights reserved. 18
  19. 19. driver.get(baseUrl + "/myVideoRental/Fron tController"); driver.findElement(By. name("shop_id")).cl ear(); Copyright © 2015 NS Solutions Corporation, All rights reserved. 19 driver.get(baseUrl + "/myVideoRental/Fron tController"); driver.findElement(By. name("shop_id")).cl ear(); driver.get(baseUrl + "/myVideoRental/Fron tController"); driver.findElement(By. name("shop_id")).cl ear(); driver.get(baseUrl + "/myVideoRental/Fron tController"); driver.findElement(By. name("shop_id")).cl ear(); driver.get(baseUrl + "/myVideoRental/Fron tController"); driver.findElement(By. name("shop_id")).cl ear(); driver.get(baseUrl + "/myVideoRental/Fron tController"); driver.findElement(By. name("shop_id")).cl ear(); LoginPage .class void login(user, passwd) void logout() boolean isLoggedIn() PageObjectパターン
  20. 20. の闇「たまに失敗」 Copyright © 2015 NS Solutions Corporation, All rights reserved. 20
  21. 21. スクリプトも完成したし、 今やこのテストは完全に 自動化された! Copyright © 2015 NS Solutions Corporation, All rights reserved. 21
  22. 22. ほらね、ちゃんと動いてる! driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); Copyright © 2015 NS Solutions Corporation, All rights reserved. 22
  23. 23. あれ、このテスト… たまに失敗してる…? driver.get(baseUrl + "/myVideoRental/FrontController"); driver.findElement(By.name("shop _id")).clear(); driver.findElement(By.name("shop _id")).sendKeys("01"); driver.findElement(By.id("Display MenuLogic")).click(); assertEquals("貸出・返却メ ニュー画面", driver.getTitle()); Copyright © 2015 NS Solutions Corporation, All rights reserved. 23
  24. 24. Copyright © 2015 NS Solutions Corporation, All rights reserved. 24
  25. 25. たまに失敗するのはなぜ? • クリックしようとした要素が不可視状態だった • ネットワークが遅くてタイムアウト • ブラウザのキャッシュがのこっていた • DBの状態がかわっていた • 信仰心がたりない • etc. etc. etc. Copyright © 2015 NS Solutions Corporation, All rights reserved. 25
  26. 26. 「このテストが失敗するのは よくあることだから大丈夫」 Copyright © 2015 NS Solutions Corporation, All rights reserved. 26 driver.get(baseUrl + "/myVideoRental/FrontCon troller"); driver.findElement(By.na me("shop_id")).clear(); driver.findElement(By.na me("shop_id")).sendKe ys("01"); (大丈夫じゃない)
  27. 27. orz Copyright © 2015 NS Solutions Corporation, All rights reserved. 27
  28. 28. たまに失敗の闇と向き合う • 同じ条件ならいつでも失敗 or いつでも成功 するテストがよいテスト! • 事前条件をそろえる • AP, DB, ブラウザ状態の初期化 • 適切にwaitする • PageObjectパターンとの組み合わせも◎ Copyright © 2015 NS Solutions Corporation, All rights reserved. 28
  29. 29. の闇ブラウザ依存 Copyright © 2015 NS Solutions Corporation, All rights reserved. 29
  30. 30. ページのレイアウト崩れが無いか 確認したい… Copyright © 2015 NS Solutions Corporation, All rights reserved. 30
  31. 31. スクリーンショットを撮ろう! Copyright © 2015 NS Solutions Corporation, All rights reserved. 31
  32. 32. File screenshotFile = ((Screenshot)driver).getScreenshotAs(file); Copyright © 2015 NS Solutions Corporation, All rights reserved. 32
  33. 33. 可視範囲のみ いろんなバー映り込む Copyright © 2015 NS Solutions Corporation, All rights reserved. 33 Internet Explorer Google Chrome Safari(iOS)
  34. 34. TakesScreenshot interface For WebDriver extending TakesScreenshot, this makes a best effort depending on the browser to return the following in order of preference: • Entire page • Current window • Visible portion of the current frame • The screenshot of the entire display containing the browser http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/TakesScreenshot.html Copyright © 2015 NS Solutions Corporation, All rights reserved. 34
  35. 35. TakesScreenshot interface(意訳) 実装するときは下記の順でどれか返してくれればいいよ。 ブラウザによってベストエフォートで実装してね。 • ページ全体 • 現在のウインドウ • 現在のフレームの可視範囲 • ブラウザも含むディスプレイ全体 http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/TakesScreenshot.html Copyright © 2015 NS Solutions Corporation, All rights reserved. 35
  36. 36. orz Copyright © 2015 NS Solutions Corporation, All rights reserved. 36
  37. 37. ブラウザ依存の闇と向き合う 世にある便利ツールを使おう! (他力本願) Copyright © 2015 NS Solutions Corporation, All rights reserved. 37
  38. 38. Seleniumベースのツール・サービス • ラッパ /DSL • SeleniumのAPIを使いやすくしてくれたり、 自然言語に近い形でテストを書けたりする • クラウドサービス • 色々なブラウザの実行環境が使えたり、 スクショや動画キャプチャ撮ってくれたりする Copyright © 2015 NS Solutions Corporation, All rights reserved. 38 参考:Seleniumテストの自動化を推し進めるクラウドサービスまとめ http://blog.htmlhifive.com/2014/12/09/selenium-cloud-services/
  39. 39. 宣伝:弊社も作ってます Pitalium Copyright © 2015 NS Solutions Corporation, All rights reserved. 39 ピ タ リ ウ ム by OSS (Apache2.0)
  40. 40. Copyright © 2015 NS Solutions Corporation, All rights reserved. 40 IE Safari Chrome Pitalium
  41. 41. テスト自動化の闇テスト自動化の闇と向き合う Copyright © 2015 NS Solutions Corporation, All rights reserved. 41
  42. 42. テスト自動化の闇と向き合うには • テストしやすい設計 • テストスクリプトに一手間 • 便利ツール・サービスを使う Copyright © 2015 NS Solutions Corporation, All rights reserved. 42
  43. 43. そして深まる闇 闇トークしたい方 hifiveブースへお越しください! Copyright © 2015 NS Solutions Corporation, All rights reserved. 43 ・ NS Solutions、NS(ロゴ)、NSSOLは、新日鉄住金ソリューションズ株式会社の登録商標です。 ・ hifive、hifive(ロゴ)は、新日鉄住金ソリューションズ株式会社の登録商標です。 ・ Pitaliumは、新日鉄住金ソリューションズ株式会社の商標です。 ・ Javaは、米国ORACLE Corp.の登録商標です。 ・ HTML5 Logo by W3C ・ その他本文記載の会社名及び製品名は、それぞれ各社の商標又は登録商標です。

×