Groovy
Geb
GebDay 22

Gebはどうして簡潔に書けるのか? 〜Gebで学ぶmethod missing〜

More than 1 year has passed since last update.


はじめに

これはGeb Advent Calendar 2016の22日目の記事です。

今日はGebの内部構造の一端をご紹介します。


Gebの簡潔表記のヒミツ

Gebといえば、下記のような簡潔な表記が可能です。

to GebishOrgHomePage

今日はこれがなぜ出来るのか? というのを解説します。


引数があるメソッドは、()を省略できる

Groovyでは、引数が1つ以上あるメソッドであれば、カッコを省略することが可能です。

なので、下記の二つのコードは等価です。

to GebishOrgHomePage

to(GebishOrgHomePage) // カッコは省略できる

そうすることこれは、このテスト(あるいは上位クラスの)toメソッドの呼び出し、ということがわかります。


親クラスにメソッド定義されてないけど??

はいその通り。そこでGroovyのmethod missingという機能が使われれいます。

method missingとはメソッド呼び出しの際に、呼び出しメソッドが見つからなかった時(継承がある場合はその上位クラスも含む)に、最終的に専用のメソッドが呼び出される機能です。

method missingといえばRubyですが、Groovyにもなんと備わっています! そのものズバリ methodMissingというメソッドが呼び出されます。

Groovyのmethod missingについてはこちらが参考になると思います。


method missingを覗きにいこう

というわけで、methodMissingの中に何が書いてあるかを見に行きましょう。

この場合は、テストケースの基底クラスである(GebSpecを見に行きます)

class GebSpec extends Specification {

Browser _browser

Browser getBrowser() {
if (_browser == null) {
_browser = createBrowser()
}
_browser
}

def methodMissing(String name, args) {
getBrowser()."$name"(*args)
}
}

そう、プライベートメソッドだと思われた処理は、getBrowser()によって取得されたbrowserの同名メソッドを呼び出すようになっています。1

ということで下記は等価なコードとなります。

to GebishOrgHomePage

browser.to(GebishOrgHomePage)

このように暗黙での処理の委譲を通して、テストケースでは省略記法で書くことができます。

ちなみに、これを繰り返してもページオブジェクトのcontentに記載されたものをメソッド呼び出しすることはできないのですが、それはAST変換という別なテクニックが使われています。

それについては別な機会にしたいと思います。


まとめ

Gebの簡潔な記述はGroovy(のmethod missing)のおかげ!