デブサミ関西2012 B-3

18,512 views

Published on

2012/9/14(金)に開催されたデブサミ関西のB-3セッションのスライドです。

ブラウザテストを自動化することにした
~TestNGとSeleniumでやってみる〜

Published in: Technology
0 Comments
29 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
18,512
On SlideShare
0
From Embeds
0
Number of Embeds
13,120
Actions
Shares
0
Downloads
84
Comments
0
Likes
29
Embeds 0
No embeds

No notes for slide

デブサミ関西2012 B-3

  1. 1. ブラウザテストを 自動化することにした   〜~TestNGとSeleniumでやってみる〜~ #kansumiB3 阪田  浩一 フリュー株式会社 ソーシャルネットワーク事業部 1 Developers Summit 20122012年9月15日土曜日 1
  2. 2. みなさん、 こんにちは こんにちは!! 2 Developers Summit 20122012年9月15日土曜日 2
  3. 3. まずは 3 Developers Summit 20122012年9月15日土曜日 3
  4. 4. 安心と定番の 4 Developers Summit 20122012年9月15日土曜日 4
  5. 5. 自己紹介から。 5 Developers Summit 20122012年9月15日土曜日 5
  6. 6. 阪田  浩一 (さかた  こういち) 6 Developers Summit 20122012年9月15日土曜日 6
  7. 7. 「すごくない」 プログラマです。 7 Developers Summit 20122012年9月15日土曜日 7
  8. 8. Twitter:  @jyukutyo はてな:  jyukutyo 「じゅくちょー」 8 Developers Summit 20122012年9月15日土曜日 8
  9. 9. 神戸出身 大阪在住 9 Developers Summit 20122012年9月15日土曜日 9
  10. 10. フリュー株式会社 ソーシャルネットワーク 事業部 10 Developers Summit 20122012年9月15日土曜日 10
  11. 11. プリントシール機と 連動した画像SNSを 作っています。 11 Developers Summit 20122012年9月15日土曜日 11
  12. 12. 半年前まで SIの世界(客先常駐)に いました。 12 Developers Summit 20122012年9月15日土曜日 12
  13. 13. こんな本とか記事 書いています。 13 Developers Summit 20122012年9月15日土曜日 13
  14. 14. 日本語版 韓国語版 14 Developers Summit 20122012年9月15日土曜日 14
  15. 15. @IT連載 次世代テスティングフレームワーク 「TestNG」 http://www.atmarkit.co.jp/fjava/ rensai4/testng01/testng01_1.html 15 Developers Summit 20122012年9月15日土曜日 15
  16. 16. 関西Javaエンジニアの会 (関ジャバ) 16 Developers Summit 20122012年9月15日土曜日 16
  17. 17. というコミュニティ やってます。 17 Developers Summit 20122012年9月15日土曜日 17
  18. 18. では 18 Developers Summit 20122012年9月15日土曜日 18
  19. 19. 今日のゴール Original Update by opofatticus 19 Developers Summit 20122012年9月15日土曜日 19
  20. 20. ブラウザでのテストを 全部人間がやる必要って あるのかなあ… 20 Developers Summit 20122012年9月15日土曜日 20
  21. 21. という疑問を 持ってもらうこと! 21 Developers Summit 20122012年9月15日土曜日 21
  22. 22. このセッションで ターゲットとする人 Original Update by ##Erika** 22 Developers Summit 20122012年9月15日土曜日 22
  23. 23. Webアプリケーション開発に関係します! JUnitでテストコード書いてます! 結合テストとかめんどくさすぎ! JenkinsとかCIツールでビルドしています! TestNG?なにそれ?おいしいの? 23 Developers Summit 20122012年9月15日土曜日 23
  24. 24. どれかに 当てはまれば OK! 24 Developers Summit 20122012年9月15日土曜日 24
  25. 25.  では 本題スタート! 25 Developers Summit 20122012年9月15日土曜日 25
  26. 26. 結合テスト(機能テスト) フェーズ… Original Update by Phillie Casablanca 26 Developers Summit 20122012年9月15日土曜日 26
  27. 27. IEとExcelとクリックの 日々が続いていた… 27 Developers Summit 20122012年9月15日土曜日 27
  28. 28. あ〜~めんどくせぇ クリックするのも 面倒でいやだ 28 Developers Summit 20122012年9月15日土曜日 28
  29. 29. そうだ! ブラウザでのテストも ユニットテストみたいに 自動化できれば…! 29 Developers Summit 20122012年9月15日土曜日 29
  30. 30. ブラウザテスト自動化… 30 Developers Summit 20122012年9月15日土曜日 30
  31. 31. よし、全力でいくか… 31 Developers Summit 20122012年9月15日土曜日 31
  32. 32. ブラウザでの 操作をコーディングする 方法がある。 32 Developers Summit 20122012年9月15日土曜日 32
  33. 33. そのためのツール 「Selenium」 33 Developers Summit 20122012年9月15日土曜日 33
  34. 34. 「Selenium」には 3つのものがある。 34 Developers Summit 20122012年9月15日土曜日 34
  35. 35. Firefoxアドオンで ブラウザでの操作を 記録する 「Selenium  IDE」 35 Developers Summit 20122012年9月15日土曜日 35
  36. 36. ブラウザでの操作を コーディングする 「Selenium  WebDriver」 (Remote  Controlの後継) 36 Developers Summit 20122012年9月15日土曜日 36
  37. 37. 複数ブラウザでの テストを複数マシンで 並列実行する 「Selenium  Grid」 37 Developers Summit 20122012年9月15日土曜日 37
  38. 38. WebDriverを使う… 38 Developers Summit 20122012年9月15日土曜日 38
  39. 39. WebDriverなら、 Java、C#、Python、 Ruby、PHP、Perl で書けるんだぜ… 39 Developers Summit 20122012年9月15日土曜日 39
  40. 40. 今回テスト対象とする アプリはこれだ! 40 Developers Summit 20122012年9月15日土曜日 40
  41. 41. 41 Developers Summit 20122012年9月15日土曜日 41
  42. 42. 41 Developers Summit 20122012年9月15日土曜日 41
  43. 43. さて、 42 Developers Summit 20122012年9月15日土曜日 42
  44. 44. ブラウザでのテストって、 基本こうだよな… 43 Developers Summit 20122012年9月15日土曜日 43
  45. 45. 1.とある画面にアクセスして、 2.入力項目になんか入れて、 3.サブミットしたら、 4.画面が再描画される。 44 Developers Summit 20122012年9月15日土曜日 44
  46. 46. これをWebDriverの コードにすると、 45 Developers Summit 20122012年9月15日土曜日 45
  47. 47. とある画面にアクセスして、 // ブラウザを表すオブジェクトを生成する WebDriver driver = new FirefoxDriver(); // URLにアクセスする driver.get("http://localhost:8080/login.html"); 46 Developers Summit 20122012年9月15日土曜日 46
  48. 48. 入力項目になんか入れて、 // 画面上の項目を取得する // HTMLのname属性で要素を指定する WebElement userId = driver.findElement(By.name("j_username")); WebElement password = driver.findElement(By.name("j_password")); // テキストボックスに値を入力する userId.sendKeys("admin"); password.sendKeys("spring"); 47 Developers Summit 20122012年9月15日土曜日 47
  49. 49. サブミットしたら、 // XPathを使って要素を取得することもできる WebElement loginButton = driver.findElement( By.xpath("//input[@type=submit]")); // ボタンをクリックして、サブミットする loginButton.click(); 48 Developers Summit 20122012年9月15日土曜日 48
  50. 50. 画面が再描画される。 // ログインが成功したら、商品一覧画面に遷移する // HTMLのタイトル文字列で遷移を確認することにする Assert.assertEquals(driver.getTitle(), "マスタ管理 - 商品一覧画面"); 49 Developers Summit 20122012年9月15日土曜日 49
  51. 51. 簡単じゃないか… 50 Developers Summit 20122012年9月15日土曜日 50
  52. 52. ブラウザも Firefoxだけじゃない 51 Developers Summit 20122012年9月15日土曜日 51
  53. 53. FirefoxDriver InternetExplorerDriver ChromeDriver OperaDriver HtmlUnitDriver AndroidDriver iPhoneDriver 52 Developers Summit 20122012年9月15日土曜日 52
  54. 54. そして、 53 Developers Summit 20122012年9月15日土曜日 53
  55. 55. 画面上の 要素を取得する方法は いくつもある。 54 Developers Summit 20122012年9月15日土曜日 54
  56. 56. 要素を取得する方法まとめ ID属性で取得する By.id("item_name") クラス名で取得する By.className("required") タグ名で取得する By.tagName("div") name属性で取得する By.name("item_name") リンクのテキストで取得する By.linkText("add item") CSSセレクタで取得する By.cssSelector("#food span") XPathで取得する By.xpath("//input") (WebElement) ((JavascriptExecutor)driver). jQueryで取得する executeScript("return $(.cheese)") 55 Developers Summit 20122012年9月15日土曜日 55
  57. 57. 話を戻して。 56 Developers Summit 20122012年9月15日土曜日 56
  58. 58. このテストは うまくいかなかった。 57 Developers Summit 20122012年9月15日土曜日 57
  59. 59. 同じテストでも 成功するときと 失敗するときが あった! 58 Developers Summit 20122012年9月15日土曜日 58
  60. 60. なぜだ! 59 Developers Summit 20122012年9月15日土曜日 59
  61. 61. ブラウザだからさ… 60 Developers Summit 20122012年9月15日土曜日 60
  62. 62. 遷移より早く、assertが実行される // ボタンをクリックして、サブミットする loginButton.click(); // ログインが成功したら、商品一覧画面に遷移する // HTMLのタイトル文字列で遷移を確認することにする Assert.assertEquals(driver.getTitle(), "マスタ管理 - 商品一覧画面"); 61 Developers Summit 20122012年9月15日土曜日 61
  63. 63. 実際の画面遷移より早く、 assertが 実行されてしまう! 62 Developers Summit 20122012年9月15日土曜日 62
  64. 64. そんなこともあろうかと! 63 Developers Summit 20122012年9月15日土曜日 63
  65. 65. タイムアウトを設定して、待つ // ボタンをクリックして、サブミットする loginButton.click(); // 3秒を超えたら、TimeoutExceptionが発生する final int timeoutInSeconds = 3; WebDriverWait wait = new WebDriverWait(driver,timeoutInSeconds); wait.until( ExpectedConditions.titleIs( "マスタ管理 - 商品一覧画面")); 64 Developers Summit 20122012年9月15日土曜日 64
  66. 66. 完璧じゃないか… 65 Developers Summit 20122012年9月15日土曜日 65
  67. 67. これだけじゃダメだ! 66 Developers Summit 20122012年9月15日土曜日 66
  68. 68. 今回のテスト対象アプリを 思い出してみよう。 67 Developers Summit 20122012年9月15日土曜日 67
  69. 69. 商品追加画面に ファイルアップロード あるんですけど… 68 Developers Summit 20122012年9月15日土曜日 68
  70. 70. できます! 69 Developers Summit 20122012年9月15日土曜日 69
  71. 71. ファイルをアップロードする // <INPUT type="file">の要素を取得する WebElement file = driver.findElement(By.id("fileUpload")); // アップロードするファイルのパスを渡す file.sendKeys("/home/jyukutyo/duke.jpeg"); 70 Developers Summit 20122012年9月15日土曜日 70
  72. 72. 商品削除画面に JavaScriptのダイアログ あるんですけど… 71 Developers Summit 20122012年9月15日土曜日 71
  73. 73. できます! 72 Developers Summit 20122012年9月15日土曜日 72
  74. 74. JavaScriptのアラートやダイアログを制御する button.click(); // アラート(ダイアログ)に制御を移す Alert alert = driver.switchTo().alert(); // OKならaccept()、キャンセルならdismiss()を呼ぶ alert.accept(); 73 Developers Summit 20122012年9月15日土曜日 73
  75. 75. ふう。 これで問題は解決し… 74 Developers Summit 20122012年9月15日土曜日 74
  76. 76. まだ終わっちゃいない! 75 Developers Summit 20122012年9月15日土曜日 75
  77. 77. いわゆる結合テストには あの仕事がある… 76 Developers Summit 20122012年9月15日土曜日 76
  78. 78. エビデンス 77 Developers Summit 20122012年9月15日土曜日 77
  79. 79. Excelに スクリーンショットを 貼るお仕事。 78 Developers Summit 20122012年9月15日土曜日 78
  80. 80. Seleniumなら、 79 Developers Summit 20122012年9月15日土曜日 79
  81. 81. スクリーンショット (キャプチャ、ハードコピー) を撮れます! 80 Developers Summit 20122012年9月15日土曜日 80
  82. 82. スクリーンショットを撮る // スクリーンショットを撮る File file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); // ファイルとして保存する FileUtils.copyFile(file, new File("/tmp/" + method.getName() + ".png")); 81 Developers Summit 20122012年9月15日土曜日 81
  83. 83. これでブラウザ操作を 自動化できた。 82 Developers Summit 20122012年9月15日土曜日 82
  84. 84. さあJUnitで テストコードを… 83 Developers Summit 20122012年9月15日土曜日 83
  85. 85. 待て  あわてるな 84 Developers Summit 20122012年9月15日土曜日 84
  86. 86. こういうものもある 85 Developers Summit 20122012年9月15日土曜日 85
  87. 87. TestNG 86 Developers Summit 20122012年9月15日土曜日 86
  88. 88. JUnitと同じく テスティング フレームワーク 87 Developers Summit 20122012年9月15日土曜日 87
  89. 89. なぜ「TestNG」か 88 Developers Summit 20122012年9月15日土曜日 88
  90. 90. XMLファイルにテスト対象を定義できる 前後処理のタイミングが豊富である テストをグループ化できる テスト間に依存関係を定義できる 89 Developers Summit 20122012年9月15日土曜日 89
  91. 91. XMLファイルにテスト対象を定義できる <!DOCTYPE suite SYSTEM "http://testng.org/ testng-1.0.dtd" > <suite name="Suite" verbose="2"> <test name="all" > <packages> <package name="test" /> </packages> </test> </suite> 90 Developers Summit 20122012年9月15日土曜日 90
  92. 92. 実行するテストを 選択できる 91 Developers Summit 20122012年9月15日土曜日 91
  93. 93. TestNGの概念 Suite Test Test Class Test Class Test Test Test Test Method Method Method Method Test Test Class Test Class Test Test Test Test Method Method Method Method 92 Developers Summit 20122012年9月15日土曜日 92
  94. 94. 前後処理のタイミングが豊富である @BeforeSuite <suite>要素に含まれる全テストメソッドを呼び出す前 @AfterSuite にアノテーションを付けたメソッドを実行する @BeforeTest <test>要素に含まれる全テストメソッドを呼び出す前に @AfterTest アノテーションを付けたメソッドを実行する @BeforeGroups そのグループにある全テストメソッドを呼び出す前にア @AfterGroups ノテーションを付けたメソッドを実行する @BeforeClass そのクラスにある全テストメソッドを呼び出す前後にアノ @AfterClass テーションを付けたメソッドを実行する @BeforeMethod そのクラスにある各テストメソッドを呼び出す前後にアノ @AfterMethod テーションを付けたメソッドを実行する 93 Developers Summit 20122012年9月15日土曜日 93
  95. 95. なぜタイミングが多いと いいの? 94 Developers Summit 20122012年9月15日土曜日 94
  96. 96. たとえば、 95 Developers Summit 20122012年9月15日土曜日 95
  97. 97. このコードは重い // ブラウザを表すオブジェクトを生成する WebDriver driver = new FirefoxDriver(); 96 Developers Summit 20122012年9月15日土曜日 96
  98. 98. Suiteの前に1回だけ インスタンスを生成させる 97 Developers Summit 20122012年9月15日土曜日 97
  99. 99. テスト実行時間が 短くできる 98 Developers Summit 20122012年9月15日土曜日 98
  100. 100. テストをグループ化して 最低限のテストだけを コミットビルドで 実行し、 99 Developers Summit 20122012年9月15日土曜日 99
  101. 101. 重いテストは 定期ビルド で実行する 100 Developers Summit 20122012年9月15日土曜日 100
  102. 102. 依存関係を設定し、 前提テストが失敗すれば、 後続のテストを スキップする 101 Developers Summit 20122012年9月15日土曜日 101
  103. 103. 他にも、 複数スレッドでテストを 実行し、 テスト実行時間を 短くできたり… 102 Developers Summit 20122012年9月15日土曜日 102
  104. 104. そして、 こういうテストコードが できた 103 Developers Summit 20122012年9月15日土曜日 103
  105. 105. protected static WebDriver driver; @BeforeSuite @Parameters({"browser"}) public static void createDriver( @Optional("firefox") String browser) { if ("firefox".equals(browser)) { driver = new FirefoxDriver(); return; } if ("safari".equals(browser)) { driver = new SafariDriver(); return; } if ("unit".equals(browser)) { driver = new HtmlUnitDriver(); return; } } 104 Developers Summit 20122012年9月15日土曜日 104
  106. 106. @BeforeMethod public void toLoginPage() { driver.get( "http://localhost:8080/login.html"); } 105 Developers Summit 20122012年9月15日土曜日 105
  107. 107. @Test public void ログインする() { WebElement userId = driver.findElement(By.name("j_username")); ...(中略)... userId.sendKeys("admin"); password.sendKeys("spring"); loginButton.click(); final int timeoutInSeconds = 3; WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds); wait.until( ExpectedConditions.titleIs("商品一覧画面")); } 106 Developers Summit 20122012年9月15日土曜日 106
  108. 108. @AfterSuite public static void closeDriver() { driver.quit(); } 107 Developers Summit 20122012年9月15日土曜日 107
  109. 109. テストコードを 実行してみる 108 Developers Summit 20122012年9月15日土曜日 108
  110. 110. 109 Developers Summit 20122012年9月15日土曜日 109
  111. 111. 109 Developers Summit 20122012年9月15日土曜日 109
  112. 112. まだだ。 まだ終わらんよ! 110 Developers Summit 20122012年9月15日土曜日 110
  113. 113. クロスブラウザ 111 Developers Summit 20122012年9月15日土曜日 111
  114. 114. Driverインスタンスを 変えればいい 112 Developers Summit 20122012年9月15日土曜日 112
  115. 115. マルチプラットフォーム ✕ クロスブラウザ 113 Developers Summit 20122012年9月15日土曜日 113
  116. 116. WindowsのIEと OS  XのSafariで 動作確認とか… 114 Developers Summit 20122012年9月15日土曜日 114
  117. 117. こんなこともあろうかと 115 Developers Summit 20122012年9月15日土曜日 115
  118. 118. 複数ブラウザでの テストを複数マシンで 並列実行する 「Selenium  Grid」 116 Developers Summit 20122012年9月15日土曜日 116
  119. 119. Test Code Selenium Hub Grid Node Node Node Browser Browser Browser 117 Developers Summit 20122012年9月15日土曜日 117
  120. 120. 使い方は簡単。 118 Developers Summit 20122012年9月15日土曜日 118
  121. 121. JARをダウンロードして起動するだけ! // start Hub java -jar selenium-server-standalone-2.25.0.jar -hub // start Node java -jar selenium-server-standalone-2.25.0.jar -role node -hub http://hubserver:4444/grid/register 119 Developers Summit 20122012年9月15日土曜日 119
  122. 122. テストコードを少し変える // 要求する実行環境。 // ブラウザのバージョンなども指定できる。 DesiredCapabilities capability = DesiredCapabilities.firefox(); // RemoteWebDriverというドライバを使う。 // 要求を満たすブラウザがNodeから選択される。 driver = new RemoteWebDriver( new URL( "http://hubserver:4444/wd/hub"), capability); 120 Developers Summit 20122012年9月15日土曜日 120
  123. 123. テストコードを少し変える // RemoteWebDriverはTakesScreenshotを実装していない。 // スクリーンショットを撮れるRemoteWebDriverの実装であれば、 // AugmenterがTakesScreenshotインタフェースを追加する。 WebDriver augmentedDriver = new Augmenter().augment(driver); File file = ((TakesScreenshot)augmentedDriver). getScreenshotAs(OutputType.FILE); FileUtils.copyFile(file, new File( "/tmp/" + method.getName() + ".png")); 121 Developers Summit 20122012年9月15日土曜日 121
  124. 124. そして、 122 Developers Summit 20122012年9月15日土曜日 122
  125. 125. Selenium  Gridを 使うとき、 123 Developers Summit 20122012年9月15日土曜日 123
  126. 126. JenkinsとSelenium   Pluginを使うと 便利! 124 Developers Summit 20122012年9月15日土曜日 124
  127. 127. Jenkinsとは 125 Developers Summit 20122012年9月15日土曜日 125
  128. 128. CIツール (Continuous  Integration) 126 Developers Summit 20122012年9月15日土曜日 126
  129. 129. 基本的な使い方としては、 127 Developers Summit 20122012年9月15日土曜日 127
  130. 130. SCMへのコミットをフックにして 最新のソースコードを取得し、 ビルドやテストを実行する アプリケーション 128 Developers Summit 20122012年9月15日土曜日 128
  131. 131. 本題と外れるので、 詳細は省略します。 129 Developers Summit 20122012年9月15日土曜日 129
  132. 132. で、Selenium  Pluginを使って Jenkinsでテストを 実行させる 130 Developers Summit 20122012年9月15日土曜日 130
  133. 133. Selenium  Pluginが便利! JenkinsサーバがHubになります! Hubを自動起動してくれます! JenkinsのスレーブをNodeとして 自動的にHubに登録してくれます! 131 Developers Summit 20122012年9月15日土曜日 131
  134. 134. Jenkinsサーバ(マスタ)が GNU/Linuxで あっても 132 Developers Summit 20122012年9月15日土曜日 132
  135. 135. 余ったWindowsマシンを Jenkinsスレーブにして 133 Developers Summit 20122012年9月15日土曜日 133
  136. 136. IEでのテストを 実行させよう! 134 Developers Summit 20122012年9月15日土曜日 134
  137. 137. デモ 135 Developers Summit 20122012年9月15日土曜日 135
  138. 138. 役割 Jenkinsのマスタサーバ。 OS X Selenium  GridのHub。 Firefoxでのテストを実施する。 Jenkinsのスレーブ。 VirtualBox上 Selenium  GridのNode。 のWindows XP IEでのテストを実施する。 136 Developers Summit 20122012年9月15日土曜日 136
  139. 139. 137 Developers Summit 20122012年9月15日土曜日 137
  140. 140. 137 Developers Summit 20122012年9月15日土曜日 137
  141. 141. JenkinsとSelenium  Gridの組み合わせは、 川口さんの記事を参考にいたしました。 138 Developers Summit 20122012年9月15日土曜日 138
  142. 142. まとめ 139 Developers Summit 20122012年9月15日土曜日 139
  143. 143. Jenkinsサイコー!(違 140 Developers Summit 20122012年9月15日土曜日 140
  144. 144. ブラウザテストも 自動化できる (部分がある) 141 Developers Summit 20122012年9月15日土曜日 141
  145. 145. めんどくさいことは できる限りマシンに やらせよう 142 Developers Summit 20122012年9月15日土曜日 142
  146. 146. 今日のソースコード Github https://github.com/jyukutyo/devsumi-­kansai2012 https://github.com/jyukutyo/devsumi-­kansai2012-­Grid 143 Developers Summit 20122012年9月15日土曜日 143
  147. 147. ご清聴 ありがとうございました! 144 Developers Summit 20122012年9月15日土曜日 144

×