Help us understand the problem. What is going on with this article?

地味だけどGebをgroovyにしている5Tips #SWTestAdvent

More than 5 years have passed since last update.

はじめに

このエントリーは ソフトウェアテストあどべんとかれんだー 2014 の9日目のエントリーです。
前日は@urasandesuさんの 『非公開メソッドの入れ替え - from "Prig: Open Source Alternative to Microsoft Fakes" Wiki -』でした。記事内の「迂廻路生成?と思われるかも」という言葉通り私も最初は?となりましたが、読み進めて行くとなるほど納得、以前レガシーコードと格闘していた私にはとても参考になるエントリーでした!

そして初めましての方は初めまして! @PoohSunnyと言います。TDD、スクラム、ソフトウェアテスト、G*、AngularJSあたりに興味があります。現在はカエルのマークの人事管理Saas作りに奮闘中です。
今日はGebというツールについて書きます。

前置き:Geb紹介

Gebとは

Screen Shot 2014-12-09 at 14.35.23.png

プログラミング言語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です。

GebConfig.groovy
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に対応しており、マルチブラウザ対応しています。それだけでなく、リモートドライバー対応しているので、リモートマシンでテスト実行が可能です(参考リンク)。ここで面倒になるのが環境の構築やメンテです。その面倒を軽減するため、SauceLabsBrowserStackといった「remote web browsers as a service」があります。Gebはこれらのサービスを、GebConfig.groovyに追記して、Gradle pluginを入れることで比較的簡単に導入することができます(参考リンク)。

弊社の場合、もう少し手抜きをしていて、CloudBeesのDEV@cloudの、Sauce OnDemandというサービスを使っています。Build.gradleに数行追加するだけ(+DEV@cloud側で設定が必要)ですが、テストの画面キャプチャ取得や実行動画の録画!を自動でしてるのでとても便利です。

まとめに代えて

いかがでした?

以上、結構マニアックなものを含めましたが、紹介してみました。Gebは細かいところに粋な気遣いがあったりするので、まだ未体験の人は是非一度触ってみてください!

明日は!?

@shin_semiyaさんです。「テストの量と重点化の方針について」とのことでわくわくしています。よろしくお願いします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away