Selenium WebDriverのカスタマイズ事例

この記事は [Selenium/Appium Advent Calendar 2014](http://qiita.com/advent-calendar/2014/selenium)の9日目の記事です。昨日の記事は @okitan さんの[「Selenium WebDriver の ElementNotVisible Error について」](http://qiita.com/okitan/items/f3bbe4a21cf08f7aefed)でした。

## はじめに ##
Seleniumを使ってWebアプリケーションのテストを自動化しよう！と思っても、テストコードを書くのには思っていたよりも工数がかかるのが現実。。orz
そこで、テストコード作成を少しでも軽減できるようにカスタマイズというか社内ライブラリ化した事例をご紹介したいと思います。

Selenium WebDriverの良い点の一つが、OSSでありJunitと統合されているため、使いやすいようにラッパーメソッドを作成したりと自分達でカスタマイズできる点です。
カスタマイズと言っても色々なレベルがありますが、Selenium本体のソースコードに手を入れてしまうとバージョンアップの追随などが大変なので、本体はそのままでプラスアルファのユーティリティを作成する方針で対応しました。

なお、本投稿はSelenium2（Selenium WebDriver）＋Java（Junit）の環境をベースとしています。

## 追加した機能 ##
- Excelを使ったデータ駆動テスト（入力＆検証）
- スクリーンショット取得（１行で）
- テスト対象のプラットフォーム（ブラウザ）切り替え
- DB初期化／エクスポート
- もろもろラッパーメソッド


など。

## Excelを使ったデータ駆動テスト ##
境界値テストなど、よくExcelでテストパターンを作成することはないでしょうか。
Excelでパターンを作成することで、複数回テストを実施してくれます。
更に、入力項目が沢山ある場合や、Excel作成者が項目を特定するためのname属性やid属性に馴染みがない場合などは、入力項目を取得してExcelのベースファイルを作成するメソッドも用意しました。
（サンプル）
・お問い合わせ画面のテスト
・「お問い合わせ項目」のラジオボタンが５つあるので、正常系として５パターンのテストを実施
![お問い合わせ   株式会社DTS.png](https://qiita-image-store.s3.amazonaws.com/0/38461/aa051b6e-639e-0d97-697d-e2cf7c817f3f.png)

・テスト用のExcelを用意
・５パターン分のデータを作成。Junitの所定のフォルダにExcelファイルを配置する。
![テスト用Excel.png](https://qiita-image-store.s3.amazonaws.com/0/38461/1a30ee49-9647-b0a7-bfe4-09d05e6ae295.png)

・Junitのテストコード（テストメソッド）
・１つのテストメソッドで、Excelからデータを読みだして５回テストを実施してくれる。
・Excelを指定する１行の記述で、全ての項目に入力してくれる。（通常のSeleniumだと20項目あったら少なくとも20行記述しないといけない）
・このサンプルでは入力だけしかしていないが、各パターンで検証をすることもできる。
![テストコード.png](https://qiita-image-store.s3.amazonaws.com/0/38461/c9a3b4da-c7d2-adb9-a83e-8ff13a3666a0.png)

## スクリーンショット取得 ##
Webアプリケーションのテストにおいて、テスト実施のエビデンスとしてよく用いられているのがスクリーンショット（画面キャプチャ）です。Selenium本体でもスクリーンショット取得する機能がありますが、フォルダやファイル名を指定する必要があります。そこで、１行でスクリーンショット取得できるユーティリティメソッドを作成しました。
なお、単にSelenium本体のメソッドをラップするだけでなく、上述したデータ駆動テストにも対応して、ブラウザのバージョンやテストメソッド名などのフォルダ分け、繰り返し回数やスクリーンショットの通し番号をファイル名に自動的に設定するようにしています。
（素のコード）
```
  File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
  FileUtils.copyFile(scrFile, new File("c:¥¥tmp¥¥screenshot.png"));
```

（ユーティリティメソッド使用）

```
       TestUtil.saveScreenshot(driver, "問い合わせ画面");  //←入力前のスクリーンショット
       
        AutoInputUtil.dataSet(driver, "DtsOtoiawase.xls", "試験データ"); //←データ入力
        driver.findElement(By.cssSelector("li > input[type=\"image\"]")).click(); //←確認画面に遷移
        
        TestUtil.saveScreenshot(driver, "入力確認画面"); //←確認画面のスクリーンショット
```
（実行結果）
・証跡用のフォルダ（Propertiesファイルで設定可）の下に以下のフォルダが作成される
・テストクラス名のフォルダ
・テストメソッド名のフォルダ
・スクリーンショット用のフォルダ。例えば証跡としてDBをエクスポートしたデータを取得する場合別フォルダを作成して整理しやすいように分けている。
・ブラウザ（バージョン含）のフォルダ。　
・その中に、テストメソッド内のコードで取得したスクリーンショット（PNG）を配置。ファイル名は、何回目のテストかということと、１テストの中での通番を自動的にプレフィックスとして付与。
![スクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/38461/2d54168b-b263-e99b-8a9b-511a168c8c2e.png)



## まとめ ##
このように、Seleniumはカスタマイズ性が高いというOSSならではの良さがあります。
特にWebDriverは開発言語でのテストフレーワークと連携しているので、既存資産を活用したカスタマイズができます。
本投稿ではカスタマイズした機能の一部を紹介しましたが、現場で作った/使ったものを再利用という形で取り込んだものを社内ライブラリとして展開しました。
[日本Seleniumユーザーコミュニティ](http://www.selenium.jp/)でも様々な情報交換や勉強会などを行っています。これからも皆さんでノウハウ・知見を蓄積していきましょう！

＃一応Apache2.0 Licenseで作成してあるのでGithubで公開とかも頭にはあるのですが、Maven非対応とかREADME.md作成とかで腰が重いかんじですorz