Geb使いから見たSelenide

# はじめに

これは[Geb Advent Calendar 2016](http://qiita.com/advent-calendar/2016/geb)の19日目の記事です。
前日は@igapyonさんの[やたら Geb を勧められるので使ってみる](http://d.hatena.ne.jp/igapyon/20161218)でした。

# Gebから見たSelenide
昨日行われた[第4回 日本Seleniumユーザーコミュニティ勉強会](https://seleniumjp.connpass.com/event/45208/)で[@shimashima35](https://twitter.com/shimashima35)さんの
[『明日から始めるSelenideによるブラウザテスト』](https://speakerdeck.com/shimashima35/ming-ri-karashi-meruselenideniyoruburauzatesuto)を見せていただいて、やっぱりSelenide便利そうだなーと思いました。私も少しだけ仕事で使ったことがあります。
今日はGebからSelenideを眺めてみたときに、こういうところに違いがあるなーという話を書きます。本当はちゃんとした比較記事にしたかったのですが、そこまでSelenideに詳しいわけではないのでやめました。

## それぞれのプロフィール
- Selenide: http://selenide.org/
- Geb: http://www.gebish.org/

# 違いがあって面白いな、と思うこと

## Selenideはブラウザの『自動テスト』ツール
おいおい、じゃあGebは違うのかと言われると、違います。
Gebはブラウザの『自動操作ツール』です。
両者のホームページを見ても
- Selenide: `Selenide is a framework for test automation`
- Geb: `very groovy browser automation`

と書いてありますね。
じゃあ具体的に何が違うのかというと、Selenideはテスト用のDSL（assert）が備わっています。

```java:Selenide
$(".message").shouldHave(text("Hello"));
```

これ、Gebにはありません。GebはテストツールとしてJUnitやSpockを利用するので、それらのassertの仕組みを利用します。
このassert、`should`系で始まるので使っていて気持ちがいいですよね。
この、かたやテストツール、かたや自動化ツールという違いは下記のような発想の違いを生んでいると思います。

### Selenideはwaitは基本使わない
Gebだとwaitは `wait { 条件 }`のように、簡潔に書ける、というのを重要視していましたが、Selenideはwaitもassertの仕組みに組み込んでいます。例えば下記のように。

```java:Selenide
$(“input”).shouldBe(visible) // 表示されるのをチェック
```

こちら、Gebは自動化ツールなので、上記のように書く発想は基本的に無いです（もちろん自分でカスタマイズすることはあるけど）。なのでこの違いは興味深いです。

### エレメントが見つからなかった時の動作が違う
昨日の日本Seleniumユーザーコミュニティ勉強会で、「Selenideはエレメントが見つからなかった時にExceptionではなくErrorを継承した例外を返すのはなぜ？」という質問が出ました。
これは完全に私の推測なのですが、これもSelenideがテストツールであることが関係していると考えています。
テストツールなので、定義してあるエレメントが見つからないのは異常事態なはずです。そのため、テストが意図的に落ちるように（catchしにくいように）Errorにしていると想像しています。
なお、Gebはエレメントが見つからない場合はExceptionを返します。

## SelenideはピュアJavaであることに重きを置いている
[この辺りのページ] (http://selenide.org/documentation/selenide-vs-selenium.html)にあるスライドなどを読んでの感想です。
`ダメなソフトウェアにはドキュメントがない。良いソフトウェアにはドキュメントが必要ない`というメッセージがあってカッコいいですよね。もう少し具体的に見ると下記のような違いがあると思います。

### 読んだ時に何が返るかが厳密にわかる
例えば下記のようなコード

```java:Selenide
$$(".errors").shouldBe(empty)
```

$$で複数のエレメントが取得できます。読んでいて複数のエレメントが返ることがわかって明確ですね。Geb(とSpock)で等価なコードを書こうとすると

```groovy:Geb
$(".errors"). isEmpty() == true 
```

となります。$は複数のときはリストで、単数のときはそのエレメントが返るようになっているためです。複数のエレメントが返った場合に`click()`などを呼ぶと例外が出ます。
これはどちらの方が良いという話ではないですが、複数返ることが明示したい時にそれがわかった方が良いと見るか、単数と複数でAPIが同じ方が良いと見るかによって判断が分かれそうです。

## IDEの協力が得やすい
ピュアJavaの利点として、IDEの補完が効きやすいことが挙げられます。昨日の勉強会でもここは評判が良かったポイントですね。
Gebでも一工夫するとIDEの補完は効くようになります(以前これについての[エントリー](http://qiita.com/PoohSunny/items/d79dc31cd94b58f041e0)書きました)。ただし補完利かす書き方であれば、Selenideとどっちを使った方が良いかを真剣に考えた方が良いと思います。
Gebは省略することで簡潔な表記にし、読むコストを減らすというのがウリだと個人的に思っています。なので書くときのコストと読むコストのどちらを取るかによって判断が分かれるかな、と考えています。

# どっちを使ったらいいの？
これは本当にケースバイケースだと思います。この辺りが判断基準になるかな、と考えています。

- IDEの補完（書く時の手間の軽減）を狙うか、読む時の負荷を下げるか
- 読んだ時に厳密さを求めるか、ある種の「空気読んで」を求めるか
- Groovyの習得コストが払えるか（あるいはDSLと割り切って使えるか）

どちらもドキュメントは充実していますし、コミッタもとても親切なので、サポート面はそんなに差がないかな、と感じます。

# 蛇足：似てるな、と思うこと
## 読み方がむずい
- Selenide: 「セレナイド」か「セレニド」
- Geb:「げぶ」ではなく「じぇぶ」

Selenideの読み方は中の人に聞いたところ、「英語だとセレナイドだしロシア語だとセレニドかなー」と返信をいただきました。
日本語だとどっちなんだろう？？　ウィキペディアだとセレニドでしたね。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr"><a href="https://twitter.com/PoohSunny">@PoohSunny</a> In English it sounds &quot;se-le-naid&quot;, and Russians say &quot;se-le-nid&quot;.<a href="https://t.co/qmayJQTmBO">https://t.co/qmayJQTmBO</a></p>&mdash; selenide (@jselenide) <a href="https://twitter.com/jselenide/status/810416701107998720">2016年12月18日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

## どちらもimplicit waitは嫌い
過去、両者のコミッタがgithub上で会話していたので、それをまとめたスライドを作ったことがあります（[こちら](https://speakerdeck.com/poohsunny/selenidetogeb)）それによると、wait周りの発想は近くて、どちらも同じような問題意識で生まれたんだなぁということがわかります。

# まとめ
Geb使いからSelenideを見ると、興味深い異同があってとても面白かったです。
それぞれに良さ、スイートスポットがあると思うので、適材適所で良いツール選びをしていけると良いですね :)