Gebを使ってみた。
G*系の勉強会で何回か聞いたことあるので名前は知っていましたが、使ったことはなかったのでとりあえず使ってみました。
資料が少なすぎる、あっても古くてそのままじゃ使えない、色々わかってる前提で書かれてる等々、苦労はありましたがなんとか動作する所までできました。
Gebとは
Webアプリケーション向けの機能テストを自動化するためのライブラリです。
http://beta.mybetabook.com/showpage/4f27c8cc0cf26106dca875c8
Internet Explorer, FireFox, Chrome などのブラウザを操作することが可能なSeleniumのWebDriverとJQueryライクな記述でコンテンツの操作や検査を可能にするAPIを組み合わせ、
Groovyの豊かな表現力により簡潔なDSLでテストスクリプトを記述することができます。
私は「ブラウザをプログラムで操作できます。」「Seleniumより簡単に書けます。」と、理解しました。
後、「Groovyで書けます。」って事。
初期設定
apply plugin: 'groovy' apply plugin: 'eclipse' repositories { mavenCentral() } dependencies { compile 'org.seleniumhq.selenium:selenium-firefox-driver:2.31.0' compile 'org.codehaus.geb:geb-core:0.7.2' }
- プロジェクト右クリック → Gradle → 全てリフレッシュ
- 「src/main/groovy」をソースフォルダとして追加
- 「target」をフォルダとして追加
- プロジェクト作成時にサンプルとして入っているソースコードを除去
HTML作成
ブラウザ上で動かすHTMLを作成。(src/main/resources)
index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>index</title> <script type="text/javascript"> function testfunc() { document.location = "./greeting.html"; } </script> </head> <body> <form action=""> <input type="text" name="username"/> <input type="button" value="CLICK ME" onclick="testfunc()" name="greet"/> </form> </body> </html>
greeting.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Greeting</title> </head> <body> <h1>Greeting Page.</h1> </body> </html>
ページクラス作成
各ページに対応したクラスを作成
IndexPage.groovy
package com.yamap55.sample.geb; import geb.Page public class IndexPage extends Page { // ブラウザに渡されるので相対パスはNG static url = "file:///c:/work/yamashita/workspace/geb_sample/src/main/resources/index.html" static at = { title == 'index' } static content = { // わかりやすくするためにHogeを後ろにつけています。 usernameHoge { $('form').username = it } greetButtonHoge(to:GreetingPage) { $('input', name:'greet') } } }
サンプルではusername、greetButtonとなっていましたが、どういう経由で実際に値を詰めてるのかわからなかったので、
ここではusernameHogeとgreetButtonHogeとしています。
GreetingPage.groovy
package com.yamap55.sample.geb; import geb.Page public class GreetingPage extends Page { static at = { title == 'Greeting' } static content = { h1Text { $('h1').text() } } }
Geb実行クラス作成
実際にブラウザでHTMLを表示し、操作させるクラスの作成。
ここは処理毎に説明を入れます。
クラス全体
GebSample.groovy
package com.yamap55.sample.geb import geb.Browser import geb.Configuration println "START" Configuration conf = new Configuration() conf.baseUrl = "." conf.driverConf = "firefox" conf.reportsDir = new File("./target") Browser.drive(conf){ to IndexPage assert at(IndexPage) report "index_page" usernameHoge "ユーザ名" greetButtonHoge.click() assert at(GreetingPage) report "greeting_page" assert h1Text == "Greeting Page." quit() } println "END"
各種設定
Configuration conf = new Configuration() conf.baseUrl = "." conf.driverConf = "firefox" conf.reportsDir = new File("./target")
driverConfはブラウザの種別、reportsDirはレポートを出力するディレクトリです。
baseUrlは何に使ってるのかわかりませんが設定しないとエラーになりました。
ブラウザ起動
Browser.drive(conf){ to IndexPage
ここで上で設定した通りfirefoxが起動され、指定されたページを表示します。
pageクラスに指定したurlが誤っているとここで落ちます。
ページの表示確認?
assert at(IndexPage)
ページクラスで指定したatクロージャーが実行されます。
今回はIndexPage.groovyで作成した通りタイトルがindexとなっているかを確認しています。(サンプルのまま。)
実際にはページの要素が正しいかなどの表示確認などを行う?
static at = { title == 'index' }
レポート出力
report "index_page"
各種設定で設定したレポート出力ディレクトリにレポートが出力されます。
実際にブラウザで表示されたHTMLとキャプチャが出力されるようです。(index_page.htmlとindex_page.png)
この一行でHTMLとキャプチャが取得されるのは嬉しい!
conf.reportsDir = new File("./target")
テキストボックスに値設定
usernameHoge "ユーザ名"
ページクラスで定義したクロージャを呼び出して値を設定します。(「usernameHoge("ユーザ名")」と同じです。)
本当は参考にあるように「usernameHoge = "ユーザ名"」としたかったのですが、やり方がわからず。
変数に入れるだけだとクロージャが呼ばれないのでうまくいかないような気がするのですが、何か方法あるのでしょう。
usernameHoge {
$('form').username = it
}
ボタンクリック
greetButtonHoge.click()
テキストボックスに値を設定する時と同じようにページクラスに定義したクロージャを呼び出して、
返り値のボタンのオブジェクトのクリックメソッドを呼び出します。*2
要素の指定がjqueryライクでわかりやすくて素敵です。
greetButtonHoge(to:GreetingPage) { $('input', name:'greet') }
別のページへ遷移
index.htmlのボタンをクリックした事でgreeting.htmlに遷移しています。
assert at(GreetingPage) report "greeting_page"
なので、GreetingPageクラスの表示確認を行なってレポートを出力。
static at = { title == 'Greeting' }
h1要素を確認
assert h1Text == "Greeting Page."
greeting.htmlに表示されているh1要素を確認します。
これもGreetingPageクラスに定義されているh1Textクロージャの返り値を比較します。
static content = { h1Text { $('h1').text() } }
ブラウザを閉じる
ここはサンプルになかったのですが、閉じないと処理が終了しないようなので加えました。
quit()
感想とか
メリット
デメリット
- 参考文献が少ない(特に日本語だと。。。)
- マニュアル等でコードはあるのでなんとかなるか。
- どの処理がどこで動作するのかがわかりにくい。
- Groovyに慣れればなんとかわかるか?(IDEAとか使うともっといい感じにわかるのかも)