WebのUIテスト自動化 - Seleniumを使ってみる


Appiumを色々触っているんですが、仕組みが同じ[Selenium](http://docs.seleniumhq.org/)もちょっと触ってみました。
だいぶ色々なことができそうなのでこちらも触りつつメモを取っていこうと思います。

##実際の動画デモ

[![スクリーンショット 2014-04-20 10.53.24.png](https://qiita-image-store.s3.amazonaws.com/0/5616/50c44142-52e7-d528-b8bd-da8b6abdcdbe.png "スクリーンショット 2014-04-20 10.53.24.png")](https://www.youtube.com/watch?v=-dZ2PLHwLI8&feature=youtu.be)
実際にどんなことができるのか、[参考動画](https://www.youtube.com/watch?v=-dZ2PLHwLI8&feature=youtu.be)を撮ってみました。

内容的にはネタな感じにしていますが、どんなことができるか分かってもらえるかと思いますｗ

##Seleniumとは

[Selenium](http://docs.seleniumhq.org/)はクロスブラウザ、クロスプラットフォームのUIテストツールです。
ブラウザに表示される要素を操作し、取得して想定されうる状態になっているかをテストできます。
また、画面のキャプチャを撮ることもできます。

検索してみると有用な記事がいくつかあるので、詳細はそちらを見てください。
ここでは簡単に触ったメモや所感を書いていきます。

* [JavaScriptテスト自動化ツールSeleniumのこれまでとこれから（前編）。第1回 日本Seleniumユーザーコミュニティ勉強会](http://www.publickey1.jp/blog/14/javascriptselenium1_selenium.html)
* [ブラウザを選ばずWebテストを自動化するSelenium](http://www.atmarkit.co.jp/ait/articles/0908/19/news109.html)


##Seleniumの準備

Selenium自体はいくつかの言語で書くことが出来ますが、今回試したのはRubyです。
（元々Rubyやってみたいと思ってたのでついでに）

なのでまずはRubyの環境を用意します。
Macであればデフォルトで入っているのでそれを使うか、あるいは`rbenv`などのバージョン管理ツールを使ってRubyをセットアップします。

コアになる機能は`selenium-webdriver`です。
なのでgemからこれをインストールしておきます。

```shell
gem install selenium-webdriver
```

###chromedriverをダウンロード

selenium-webdriverからそれぞれの **ブラウザ用のdriver** に接続して、そこから各種ブラウザを操作する、という流れになります。
デフォルトでFirefoxは起動できるようでしたが、Chromeは自分でdriverをダウンロードしてこないといけないようです。

[chromedriverのダウンロード](https://sites.google.com/a/chromium.org/chromedriver/downloads)


##テストの記述

テストはとても簡単に書けるようになっています。
まずはテストコードを見てもらうと分かると思います。

```ruby
require "selenium-webdriver"

# Firefox用のドライバを使う
driver = Selenium::WebDriver.for :firefox

# Googleにアクセス
driver.navigate.to "http://google.com"

# `q`というnameを持つ要素を取得
element = driver.find_element(:name, 'q')

# `Hello WebDriver!`という文字を、上記で取得したinput要素に入力
element.send_keys "Hello WebDriver!"

# submitを実行する（つまり検索する）
element.submit

# 表示されたページのタイトルをコンソールに出力
puts driver.title

# テストを終了する（ブラウザを終了させる）
driver.quit
```

これはFirefoxを起動し、Googleに移動したあとで`q`という名前のついたフォームの要素に`Hello WebDriver!`と入力し送信する、というものです。

最後の`driver.quit`によってブラウザが終了します。
テストツールではありますが、これを使うことでなにかの自動処理を書いたりもできそうですね。

###要素を取得

要素の取得には`find_element`メソッドを使います。
第一引数に検索する対象、第二引数に内容を渡します。

```ruby
driver = Selenium::WebDriver.for :firefox

driver.navigate.to "http://google.com"
element = driver.find_element :tag_name, "div"
```

####指定できるもの
| タイプ             | 意味        |
|-------------------|-------------|
|:class             | 'ClassName' |
|:class_name        | 'ClassName' |
|:css               | 'CssSelector' |
|:id                | 'Id' |
|:link              | 'LinkText' |
|:link_text         | 'LinkText' |
|:name              | 'Name' |
|:partial_link_text | 'PartialLinkText' |
|:tag_name          | 'TagName' |
|:xpath             | 'Xpath' |


###特定の要素が出てくるのを待つ

さらに、なにがしかの要素が出現するのを待って処理をする、ということもできるようになっています。

```ruby
# fooという要素が現れるまで待つ
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # タイムアウト10秒
wait.until { driver.find_element(:id => "foo") }
```

###単純に目視で確認するためにwaitを挟む

これの場合は単純に、Rubyにある`sleep`メソッドを使うことで実現できます。

```ruby
# 5秒待ってから処理を実行する
sleep 5

element = driver.find_element(:id, "hoge")
element.click
```

##JavaScriptを実行する

JavaScriptを実行させることもできます。
さらに実行した結果を受け取ることもできます。
以下のように`execute_script`メソッドに実行したいJSを書きます。

```ruby
# alertを表示する
driver.execute_script "alert('hoge');"

# `loation.href`の実行結果を受け取る
url = driver.execute_script "return location.href;"
```