デブサミ関西2012 b-3
DESCRIPTION
2012/9/14(金)に開催されたデブサミ関西のB-3セッションのスライドです。 ブラウザテストを自動化することにした ~TestNGとSeleniumでやってみる〜TRANSCRIPT
Developers Summit 2012
阪田 浩一フリュー株式会社ソーシャルネットワーク事業部
#kansumiB3
ブラウザテストを自動化することにした 〜~TestNGとSeleniumでやってみる〜~
1
12012年9月15日土曜日
Developers Summit 2012
みなさん、こんにちはこんにちは!!
2
22012年9月15日土曜日
Developers Summit 2012
まずは
3
32012年9月15日土曜日
Developers Summit 2012
安心と定番の
4
42012年9月15日土曜日
Developers Summit 2012
自己紹介から。
5
52012年9月15日土曜日
Developers Summit 2012
阪田 浩一(さかた こういち)
6
62012年9月15日土曜日
Developers Summit 2012
「すごくない」プログラマです。
7
72012年9月15日土曜日
Developers Summit 2012
Twitter: @jyukutyoはてな: jyukutyo「じゅくちょー」
8
82012年9月15日土曜日
Developers Summit 2012
神戸出身大阪在住
9
92012年9月15日土曜日
Developers Summit 2012
フリュー株式会社ソーシャルネットワーク
事業部
10
102012年9月15日土曜日
Developers Summit 2012
プリントシール機と連動した画像SNSを作っています。
11
112012年9月15日土曜日
Developers Summit 2012
半年前までSIの世界(客先常駐)に
いました。
12
122012年9月15日土曜日
Developers Summit 2012
こんな本とか記事書いています。
13
132012年9月15日土曜日
Developers Summit 2012
日本語版 韓国語版
14
142012年9月15日土曜日
Developers Summit 2012
@IT連載次世代テスティングフレームワーク
「TestNG」http://www.atmarkit.co.jp/fjava/rensai4/testng01/testng01_1.html
15
152012年9月15日土曜日
Developers Summit 2012
関西Javaエンジニアの会(関ジャバ)
16
162012年9月15日土曜日
Developers Summit 2012
というコミュニティやってます。
17
172012年9月15日土曜日
Developers Summit 2012
では
18
182012年9月15日土曜日
Developers Summit 2012
今日のゴール
Original Update by opofatticus19
192012年9月15日土曜日
Developers Summit 2012
ブラウザでのテストを全部人間がやる必要ってあるのかなあ…
20
202012年9月15日土曜日
Developers Summit 2012
という疑問を持ってもらうこと!
21
212012年9月15日土曜日
Developers Summit 2012
このセッションでターゲットとする人
Original Update by ##Erika**22
222012年9月15日土曜日
Developers Summit 2012
Webアプリケーション開発に関係します!
JUnitでテストコード書いてます!
結合テストとかめんどくさすぎ!
JenkinsとかCIツールでビルドしています!
TestNG?なにそれ?おいしいの?
23
232012年9月15日土曜日
Developers Summit 2012
どれかに当てはまればOK!
24
242012年9月15日土曜日
Developers Summit 2012
では本題スタート!
25
252012年9月15日土曜日
Developers Summit 2012 Original Update by Phillie Casablanca
結合テスト(機能テスト)フェーズ…
26
262012年9月15日土曜日
Developers Summit 2012
IEとExcelとクリックの日々が続いていた…
27
272012年9月15日土曜日
Developers Summit 2012
あ〜~めんどくせぇ
クリックするのも面倒でいやだ
28
282012年9月15日土曜日
Developers Summit 2012
そうだ!ブラウザでのテストもユニットテストみたいに自動化できれば…!
29
292012年9月15日土曜日
Developers Summit 2012
ブラウザテスト自動化…
30
302012年9月15日土曜日
Developers Summit 2012
よし、全力でいくか…
31
312012年9月15日土曜日
Developers Summit 2012
ブラウザでの操作をコーディングする
方法がある。
32
322012年9月15日土曜日
Developers Summit 2012
そのためのツール「Selenium」
33
332012年9月15日土曜日
Developers Summit 2012
「Selenium」には3つのものがある。
34
342012年9月15日土曜日
Developers Summit 2012
Firefoxアドオンでブラウザでの操作を
記録する「Selenium IDE」
35
352012年9月15日土曜日
Developers Summit 2012
ブラウザでの操作をコーディングする
「Selenium WebDriver」(Remote Controlの後継)
36
362012年9月15日土曜日
Developers Summit 2012
複数ブラウザでのテストを複数マシンで並列実行する
「Selenium Grid」
37
372012年9月15日土曜日
Developers Summit 2012
WebDriverを使う…
38
382012年9月15日土曜日
Developers Summit 2012
WebDriverなら、Java、C#、Python、Ruby、PHP、Perlで書けるんだぜ…
39
392012年9月15日土曜日
Developers Summit 2012
今回テスト対象とするアプリはこれだ!
40
402012年9月15日土曜日
Developers Summit 2012 41
412012年9月15日土曜日
Developers Summit 2012 41
412012年9月15日土曜日
Developers Summit 2012
さて、
42
422012年9月15日土曜日
Developers Summit 2012
ブラウザでのテストって、基本こうだよな…
43
432012年9月15日土曜日
Developers Summit 2012
1.とある画面にアクセスして、
2.入力項目になんか入れて、
3.サブミットしたら、
4.画面が再描画される。
44
442012年9月15日土曜日
Developers Summit 2012
これをWebDriverのコードにすると、
45
452012年9月15日土曜日
Developers Summit 2012
とある画面にアクセスして、// ブラウザを表すオブジェクトを生成するWebDriver driver = new FirefoxDriver();
// URLにアクセスするdriver.get("http://localhost:8080/login.html");
46
462012年9月15日土曜日
Developers Summit 2012
入力項目になんか入れて、// 画面上の項目を取得する// 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
472012年9月15日土曜日
Developers Summit 2012
サブミットしたら、// XPathを使って要素を取得することもできるWebElement loginButton =
driver.findElement(By.xpath("//input[@type='submit']"));
// ボタンをクリックして、サブミットするloginButton.click();
48
482012年9月15日土曜日
Developers Summit 2012
画面が再描画される。// ログインが成功したら、商品一覧画面に遷移する// HTMLのタイトル文字列で遷移を確認することにするAssert.assertEquals(driver.getTitle(),
"マスタ管理 - 商品一覧画面");
49
492012年9月15日土曜日
Developers Summit 2012
簡単じゃないか…
50
502012年9月15日土曜日
Developers Summit 2012
ブラウザもFirefoxだけじゃない
51
512012年9月15日土曜日
Developers Summit 2012
FirefoxDriver
InternetExplorerDriver
ChromeDriver
OperaDriver
HtmlUnitDriver
AndroidDriver
iPhoneDriver52
522012年9月15日土曜日
Developers Summit 2012
そして、
53
532012年9月15日土曜日
Developers Summit 2012
画面上の要素を取得する方法はいくつもある。
54
542012年9月15日土曜日
Developers Summit 2012
要素を取得する方法まとめ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")
jQueryで取得する(WebElement) ((JavascriptExecutor)driver).
executeScript("return $('.cheese')")
55
552012年9月15日土曜日
Developers Summit 2012
話を戻して。
56
562012年9月15日土曜日
Developers Summit 2012
このテストはうまくいかなかった。
57
572012年9月15日土曜日
Developers Summit 2012
同じテストでも成功するときと失敗するときがあった!
58
582012年9月15日土曜日
Developers Summit 2012
なぜだ!
59
592012年9月15日土曜日
Developers Summit 2012
ブラウザだからさ…
60
602012年9月15日土曜日
Developers Summit 2012
遷移より早く、assertが実行される// ボタンをクリックして、サブミットするloginButton.click();
// ログインが成功したら、商品一覧画面に遷移する// HTMLのタイトル文字列で遷移を確認することにするAssert.assertEquals(driver.getTitle(),
"マスタ管理 - 商品一覧画面");
61
612012年9月15日土曜日
Developers Summit 2012
実際の画面遷移より早く、assertが
実行されてしまう!
62
622012年9月15日土曜日
Developers Summit 2012
そんなこともあろうかと!
63
632012年9月15日土曜日
Developers Summit 2012
タイムアウトを設定して、待つ// ボタンをクリックして、サブミットするloginButton.click();
// 3秒を超えたら、TimeoutExceptionが発生するfinal int timeoutInSeconds = 3;WebDriverWait wait =
new WebDriverWait(driver,timeoutInSeconds);wait.until(
ExpectedConditions.titleIs("マスタ管理 - 商品一覧画面"));
64
642012年9月15日土曜日
Developers Summit 2012
完璧じゃないか…
65
652012年9月15日土曜日
Developers Summit 2012
これだけじゃダメだ!
66
662012年9月15日土曜日
Developers Summit 2012
今回のテスト対象アプリを思い出してみよう。
67
672012年9月15日土曜日
Developers Summit 2012
商品追加画面にファイルアップロードあるんですけど…
68
682012年9月15日土曜日
Developers Summit 2012
できます!
69
692012年9月15日土曜日
Developers Summit 2012
ファイルをアップロードする// <INPUT type="file">の要素を取得するWebElement file =
driver.findElement(By.id("fileUpload"));
// アップロードするファイルのパスを渡すfile.sendKeys("/home/jyukutyo/duke.jpeg");
70
702012年9月15日土曜日
Developers Summit 2012
商品削除画面にJavaScriptのダイアログあるんですけど…
71
712012年9月15日土曜日
Developers Summit 2012
できます!
72
722012年9月15日土曜日
Developers Summit 2012
JavaScriptのアラートやダイアログを制御するbutton.click();
// アラート(ダイアログ)に制御を移すAlert alert = driver.switchTo().alert();
// OKならaccept()、キャンセルならdismiss()を呼ぶalert.accept();
73
732012年9月15日土曜日
Developers Summit 2012
ふう。これで問題は解決し…
74
742012年9月15日土曜日
Developers Summit 2012
まだ終わっちゃいない!
75
752012年9月15日土曜日
Developers Summit 2012
いわゆる結合テストにはあの仕事がある…
76
762012年9月15日土曜日
Developers Summit 2012
エビデンス77
772012年9月15日土曜日
Developers Summit 2012
Excelにスクリーンショットを貼るお仕事。
78
782012年9月15日土曜日
Developers Summit 2012
Seleniumなら、
79
792012年9月15日土曜日
Developers Summit 2012
スクリーンショット(キャプチャ、ハードコピー)
を撮れます!
80
802012年9月15日土曜日
Developers Summit 2012
スクリーンショットを撮る// スクリーンショットを撮るFile file = ((TakesScreenshot)
driver).getScreenshotAs(OutputType.FILE);
// ファイルとして保存するFileUtils.copyFile(file, new File("/tmp/" +
method.getName() + ".png"));
81
812012年9月15日土曜日
Developers Summit 2012
これでブラウザ操作を自動化できた。
82
822012年9月15日土曜日
Developers Summit 2012
さあJUnitでテストコードを…
83
832012年9月15日土曜日
Developers Summit 2012
待て あわてるな
84
842012年9月15日土曜日
Developers Summit 2012
こういうものもある
85
852012年9月15日土曜日
Developers Summit 2012
TestNG
86
862012年9月15日土曜日
Developers Summit 2012
JUnitと同じくテスティングフレームワーク
87
872012年9月15日土曜日
Developers Summit 2012
なぜ「TestNG」か
88
882012年9月15日土曜日
Developers Summit 2012
XMLファイルにテスト対象を定義できる
前後処理のタイミングが豊富である
テストをグループ化できる
テスト間に依存関係を定義できる
89
892012年9月15日土曜日
Developers Summit 2012
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
902012年9月15日土曜日
Developers Summit 2012
実行するテストを選択できる
91
912012年9月15日土曜日
Developers Summit 2012
TestNGの概念SuiteTest
Test ClassTest
MethodTest
Method
Test ClassTest
MethodTest
Method
TestTest Class
Test Method
Test Method
Test ClassTest
MethodTest
Method
92
922012年9月15日土曜日
Developers Summit 2012
前後処理のタイミングが豊富である@BeforeSuite@AfterSuite
<suite>要素に含まれる全テストメソッドを呼び出す前にアノテーションを付けたメソッドを実行する
@BeforeTest@AfterTest
<test>要素に含まれる全テストメソッドを呼び出す前にアノテーションを付けたメソッドを実行する
@BeforeGroups@AfterGroups
そのグループにある全テストメソッドを呼び出す前にアノテーションを付けたメソッドを実行する
@BeforeClass@AfterClass
そのクラスにある全テストメソッドを呼び出す前後にアノテーションを付けたメソッドを実行する
@BeforeMethod@AfterMethod
そのクラスにある各テストメソッドを呼び出す前後にアノテーションを付けたメソッドを実行する
93
932012年9月15日土曜日
Developers Summit 2012
なぜタイミングが多いといいの?
94
942012年9月15日土曜日
Developers Summit 2012
たとえば、
95
952012年9月15日土曜日
Developers Summit 2012
このコードは重い
// ブラウザを表すオブジェクトを生成するWebDriver driver = new FirefoxDriver();
96
962012年9月15日土曜日
Developers Summit 2012
Suiteの前に1回だけインスタンスを生成させる
97
972012年9月15日土曜日
Developers Summit 2012
テスト実行時間が短くできる
98
982012年9月15日土曜日
Developers Summit 2012
テストをグループ化して最低限のテストだけをコミットビルドで実行し、
99
992012年9月15日土曜日
Developers Summit 2012
重いテストは定期ビルドで実行する
100
1002012年9月15日土曜日
Developers Summit 2012
依存関係を設定し、前提テストが失敗すれば、
後続のテストをスキップする
101
1012012年9月15日土曜日
Developers Summit 2012
他にも、複数スレッドでテストを
実行し、テスト実行時間を短くできたり…
102
1022012年9月15日土曜日
Developers Summit 2012
そして、こういうテストコードが
できた
103
1032012年9月15日土曜日
Developers Summit 2012
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
1042012年9月15日土曜日
Developers Summit 2012
@BeforeMethodpublic void toLoginPage() { driver.get(
"http://localhost:8080/login.html");}
105
1052012年9月15日土曜日
Developers Summit 2012
@Testpublic 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
1062012年9月15日土曜日
Developers Summit 2012
@AfterSuitepublic static void closeDriver() { driver.quit();}
107
1072012年9月15日土曜日
Developers Summit 2012
テストコードを実行してみる
108
1082012年9月15日土曜日
Developers Summit 2012 109
1092012年9月15日土曜日
Developers Summit 2012 109
1092012年9月15日土曜日
Developers Summit 2012
まだだ。まだ終わらんよ!
110
1102012年9月15日土曜日
Developers Summit 2012
クロスブラウザ
111
1112012年9月15日土曜日
Developers Summit 2012
Driverインスタンスを変えればいい
112
1122012年9月15日土曜日
Developers Summit 2012
マルチプラットフォーム✕
クロスブラウザ
113
1132012年9月15日土曜日
Developers Summit 2012
WindowsのIEとOS XのSafariで動作確認とか…
114
1142012年9月15日土曜日
Developers Summit 2012
こんなこともあろうかと
115
1152012年9月15日土曜日
Developers Summit 2012
複数ブラウザでのテストを複数マシンで並列実行する
「Selenium Grid」
116
1162012年9月15日土曜日
Selenium Grid
Developers Summit 2012
Hub
Node Node Node
Browser Browser Browser
Test Code
117
1172012年9月15日土曜日
Developers Summit 2012
使い方は簡単。
118
1182012年9月15日土曜日
Developers Summit 2012
JARをダウンロードして起動するだけ!// start Hubjava -jar selenium-server-standalone-2.25.0.jar -hub
// start Nodejava -jar selenium-server-standalone-2.25.0.jar -role node -hub http://hubserver:4444/grid/register
119
1192012年9月15日土曜日
Developers Summit 2012
テストコードを少し変える// 要求する実行環境。// ブラウザのバージョンなども指定できる。DesiredCapabilities capability =
DesiredCapabilities.firefox();
// RemoteWebDriverというドライバを使う。// 要求を満たすブラウザがNodeから選択される。driver = new RemoteWebDriver(new URL("http://hubserver:4444/wd/hub"), capability);
120
1202012年9月15日土曜日
Developers Summit 2012
テストコードを少し変える// 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
1212012年9月15日土曜日
Developers Summit 2012
そして、
122
1222012年9月15日土曜日
Developers Summit 2012
Selenium Gridを使うとき、
123
1232012年9月15日土曜日
Developers Summit 2012
JenkinsとSelenium Pluginを使うと便利!
124
1242012年9月15日土曜日
Developers Summit 2012
Jenkinsとは
125
1252012年9月15日土曜日
Developers Summit 2012
CIツール(Continuous Integration)
126
1262012年9月15日土曜日
Developers Summit 2012
基本的な使い方としては、
127
1272012年9月15日土曜日
Developers Summit 2012
SCMへのコミットをフックにして最新のソースコードを取得し、ビルドやテストを実行するアプリケーション
128
1282012年9月15日土曜日
Developers Summit 2012
本題と外れるので、詳細は省略します。
129
1292012年9月15日土曜日
Developers Summit 2012
で、Selenium Pluginを使ってJenkinsでテストを実行させる
130
1302012年9月15日土曜日
Developers Summit 2012
JenkinsサーバがHubになります!
Hubを自動起動してくれます!
JenkinsのスレーブをNodeとして自動的にHubに登録してくれます!
Selenium Pluginが便利!
131
1312012年9月15日土曜日
Developers Summit 2012
Jenkinsサーバ(マスタ)がGNU/Linuxであっても
132
1322012年9月15日土曜日
Developers Summit 2012
余ったWindowsマシンをJenkinsスレーブにして
133
1332012年9月15日土曜日
Developers Summit 2012
IEでのテストを実行させよう!
134
1342012年9月15日土曜日
Developers Summit 2012
デモ
135
1352012年9月15日土曜日
Developers Summit 2012
役割
OS XJenkinsのマスタサーバ。
Selenium GridのHub。
Firefoxでのテストを実施する。
VirtualBox上のWindows XP
Jenkinsのスレーブ。
Selenium GridのNode。
IEでのテストを実施する。
136
1362012年9月15日土曜日
Developers Summit 2012 137
1372012年9月15日土曜日
Developers Summit 2012 137
1372012年9月15日土曜日
Developers Summit 2012
JenkinsとSelenium Gridの組み合わせは、川口さんの記事を参考にいたしました。
138
1382012年9月15日土曜日
Developers Summit 2012
まとめ
139
1392012年9月15日土曜日
Developers Summit 2012
Jenkinsサイコー!(違
140
1402012年9月15日土曜日
Developers Summit 2012
ブラウザテストも自動化できる(部分がある)
141
1412012年9月15日土曜日
Developers Summit 2012
めんどくさいことはできる限りマシンにやらせよう
142
1422012年9月15日土曜日
Developers Summit 2012
今日のソースコードGithub
https://github.com/jyukutyo/devsumi-kansai2012https://github.com/jyukutyo/devsumi-kansai2012-Grid
143
1432012年9月15日土曜日
Developers Summit 2012
ご清聴ありがとうございました!
144
1442012年9月15日土曜日