はじめに
このエントリーは ソフトウェアテストあどべんとかれんだー 2014 の9日目のエントリーです。
前日は@urasandesuさんの 『非公開メソッドの入れ替え - from "Prig: Open Source Alternative to Microsoft Fakes" Wiki -』でした。記事内の「迂廻路生成?と思われるかも」という言葉通り私も最初は?となりましたが、読み進めて行くとなるほど納得、以前レガシーコードと格闘していた私にはとても参考になるエントリーでした!
そして初めましての方は初めまして! @PoohSunnyと言います。TDD、スクラム、ソフトウェアテスト、G*、AngularJSあたりに興味があります。現在はカエルのマークの人事管理Saas作りに奮闘中です。
今日はGebというツールについて書きます。
前置き:Geb紹介
Gebとは
プログラミング言語Groovyを用いたWebアプリケーション向けの機能テストライブラリで、「じぇぶ」と読みます(「げぶ」ではない)。本家のページ(英語)には、「とてもgroovyなブラウザオートメーション」と書かれてします(groovyって単語には、「魅惑的な」とか「すばらしい」などの意味があります。以下本エントリー中のgroovyという単語は同じ意味で使っています)。さまざまな説明やサンプルコードも本家のページにあります。ライセンスはApache License, Version 2.0です。
日本語の紹介記事
日本語でも既に紹介エントリーやスライドが多数あります。ここではリンクの紹介だけしておきます。
今日のテーマ
Gebのホームページや上記エントリーを見ただけでも、「あ、Gebって良さそう!」って感じるかもしれませんが、実際使ってみると他にもいろいろとGebには地味な?便利機能があります。
今年一年、仕事でそこそこGebテストを書いてきた中で、いろんな「あーこれ地味だけどgroovyだわー」というのに出会ったので、それらを紹介します。
Gebを導入しようと思えたり、導入した際に使って見ようと思えたりしていただけるとハッピーです。
地味だけどGebをgroovyにしている5Tips
1.attribute取得時にマッチャーが使える
Gebの説明で真っ先に上がる良い点は、下記のようにJQueryライクな簡潔なAPIでwebのエレメントを取得できることです。
$("h1", text: "All about Geb")
$("div").find(".b")
で、このtext:XXX
の部分には、ただテキストを入れるだけではなく、マッチャーを使うことができます(参考リンク)。
例えば、
$("p", text: contains("Geb"))
上記コードの場合は、テキストに「Geb」と入っているエレメントが全て取得されます。他にもcontainsとか、startWithがあり、時々お世話になります。ちなみに下記のように、
$("p", text: ~/p./).size() == 2
といったように正規表現も使うことができます。
とても便利ですが、反面意図しないエレメントを取得してしまう可能性があるので、その点ご注意ください。
Gebのドキュメントでは下記のような例を見つけました。
class GoogleResultsPage extends Page {
static at = { waitFor { title.endsWith("Google Search") } }
...
2.waitの記述が楽
Gebでの基本的なwaitは
waitFor {
$("p.status").text() == "Asynchronous operation complete!"
}
というようにwaitFor{ 条件 }
で記述できます。
私以前はJava - WebDriverで書いていたのですが、
wait.until(visibilityOfElementLocated(By.id("hoge"));
とか書いていた気がします。Gebだと同じことは
waitFor { $("div", id: "hoge").isDisplayed() }
と書けます。見た目だいぶシンプルになったと思います。
もしページオブジェクトパターンで記述しているのであれば、下記のように書くこともできます。
class IndexPage extends Page {
static at = {
title == "Top Page"
}
static content = {
saveButton(wait: true) { $("button", class: "btn") }
}
}
saveButton
を利用する際、まだ表示されていなければ表示を待ってくれます。タイムアウトはGebConfigで設定したり、(wait: 30)
のように引数で設定することもできます。
3.Cookieの自動クリア
Geb + Spockで使う時は、各メソッドの実行毎にCookieをクリアしてくれます(参考リンク)。変にキャッシュが残っていると、意図しない動作をすることがあるためです。
もちろん、自動でクリアをしてくれない方がいい場合もあって、その時はGebCongif.groovy
にパラメーターを追加すればOKです。
autoClearCookies = false
さらに、Spockの@Stepwise
アノテーションをテストにつけると、Cookieはクリアされなくなります。@Stepwiseをつけるということは、各ステップ毎に連続してテストをしたいケースでしょうから、こういった細かい気遣いは嬉しいです。
4.シンタックスシュガー
続いて、本当に地味だったけど、使って嬉しかったシンタックスシュガー2選。
ボタンのdisableを取得
たとえば、ボタンのエレメントのdisableを取りたい!というときに、
deleteSelectedButton.@disabled == 'true'
上記コードでとれます(参考リンク)。
sendkey
WebDriverで書くと、
driver.FindElement(By.Id("firstname"));
textbox1.SendKeys("Hello World");
と書くSendKeyイベントは、Gebだと
$("input", id: "firstName").value("hoge")
と書けます。もっとサボるなら
$("input", name: "firstName") << "hoge"
Groovyのファイルへの書き込みとかと一緒です(参考リンク)。
5.Cloud Browser Testing対応
Gebは各種WebDriverに対応しており、マルチブラウザ対応しています。それだけでなく、リモートドライバー対応しているので、リモートマシンでテスト実行が可能です(参考リンク)。ここで面倒になるのが環境の構築やメンテです。その面倒を軽減するため、SauceLabsやBrowserStackといった「remote web browsers as a service」があります。Gebはこれらのサービスを、GebConfig.groovy
に追記して、Gradle pluginを入れることで比較的簡単に導入することができます(参考リンク)。
弊社の場合、もう少し手抜きをしていて、CloudBeesのDEV@cloudの、Sauce OnDemandというサービスを使っています。Build.gradle
に数行追加するだけ(+DEV@cloud側で設定が必要)ですが、テストの画面キャプチャ取得や実行動画の録画!を自動でしてるのでとても便利です。
まとめに代えて
いかがでした?
以上、結構マニアックなものを含めましたが、紹介してみました。Gebは細かいところに粋な気遣いがあったりするので、まだ未体験の人は是非一度触ってみてください!
明日は!?
@shin_semiyaさんです。「テストの量と重点化の方針について」とのことでわくわくしています。よろしくお願いします。