亀岡的プログラマ日記

京都のベッドタウン、亀岡よりだらだらとお送りいたします。

Geb 公式チュートリアル読み解きシリーズ③: ページオブジェクトとモジュール #gebadvent

これは、Geb Advent Calendar 12/23 の記事です。

さて、前々回前回に続き、Gebの公式チュートリアル解説の続きです。

今回は、テストメソッドの中で使われているGebの機能、特にページオブジェクトについて見ていきましょう。

ページオブジェクト

ページオブジェクトとは

まずは、以下のコードを見てください。

when:
to GebishOrgHomePage
manualsMenu.links[0].click()

then:
at TheBookOfGebPage

これが、ページオブジェクトを利用したコードです。 一行ずつ見てみましょう。

まず、to GebishOrgHomePageGebishOrgHomePage へと移動します。

次に、 manualsMenu.links[0].click() で、リンクをクリックしているのですが、実はテストメソッドには manualsMenu の定義はありません。 実はto などでページ移動をした際には、そのページがもつ部品については、テストメソッドから直接アクセスできるようになっているのです。

最後のat TheBookOfGebPageアサーションの部分です。なんのアサーションをしているかというと、「TheBookOfGebPage にいまブラウザのページが表示されているかどうか」をアサーションしているのです。

このように、テストからは直接DOM要素を触るのではなく、「ページ」というオブジェクトを操作する形でテストを記述するのが、Gebの主要な書き方となります。

では、テストでこのように書くためには、どのように定義すればいいのでしょうか

ページオブジェクト定義の方法

その定義の部分が、以下になります。

class GebishOrgHomePage extends Page {

    static at = { title == "Geb - Very Groovy Browser Automation" }

    static content = {
        manualsMenu { $("#header-content ul li", 0).module(MenuModule) }
    }
}

Page を拡張したクラスとして定義することで、ページオブジェクトとして定義されているのですね。

ではまず、 to でページに移動するところはどうなっているのでしょう?こちらには、特にページの情報は書いていませんね・・・

実は、全ページに共通の baseUrlGebConfig.groovy に定義されています。

baseUrl = "http://gebish.org"

特にページ情報が書いていない場合は、 baseUrl のトップディレクトリに移動しますので、最初の to GebishOrgHomePage で遷移するのは、 baseUrl で定義されている http://gebish.org の部分となります。

では次に、manualsMenu.links[0].click() でアクセスされている manualsMenu についてです。 こちらについては、content プロパティの中に定義されていますね。

static content = {
    manualsMenu { $("#header-content ul li", 0).module(MenuModule) }
}

このように、content プロパティとして定義することで、ページが持つ部品を定義することができます。

.module(MenuModule) の部分は、MenuModule というモジュールオブジェクトとして定義するという意味ですが、これは後述します。

最後に at でのアサーションの部分です。こちらは対応するのは以下の部分になります。

static at = { title == "Geb - Very Groovy Browser Automation" }

at プロパティとして、そのページを表示した時に満たしておくべき条件を記述していきます。 例えば上記では、ページタイトルが "Geb - Very Groovy Browser Automation" なのかどうか、というのをそのページが満たすべき状態、としているのですね。

モジュールオブジェクト

ページオブジェクトがWebページそれぞれを抽象化したオブジェクトとなるのですが、メニューやヘッダー・フッターなど、ページをまたいで利用するような部品もあるでしょう。それらを共通化するために使われるのが、モジュールとなります。

この例では、manualsMenu { $("#header-content ul li", 0).module(MenuModule) } のようにメニュー部分をモジュールとして読み出しています。

こうすることで、テストメソッドから、manualsMenu.links[0].click() のように MenuModule が持つ links オブジェクトをりようすることができています。 では、どのようにモジュールオブジェクトを定義するのでしょうか。

定義の方法

モジュールの定義は以下のようになります。

class MenuModule extends Module {

    static content = {
        toggle { children("span") }
        links { $('.link-list li a') }
    }
}

Module クラスを拡張することで、モジュールオブジェクトとして利用できます。実は他の中身はページオブジェクトと大差はありません。 ここでは、 content プロパティを同様に定義しています。この中にある links を使っているのが、manualsMenu.links[0].click() の部分となります。

まとめ

ざっと見てきたように、このサンプルだけでも食べきれないくらい、Gebの面白い機能が詰まっています。 動く例題として、Gebの公式サンプルをしっかり読んでみるのは、Gebを使いこなす良い一歩になるのではと思います。

それでは、楽しいテストライフを!