Webアプリケーションのテスト自動化

社内向け説明資料。SeleniumWebdriverを用いた自動テストの概要について。

# 基本情報

* 執筆：2018/07/23
* 更新：2020/01/16
* OS:Windows10

# Seleniumとは
Webアプリケーションをテストするためのフレームワーク（ライブラリ）、といった書き方がしてあるサイトが多いが、「Webブラウザに特化したRPAツール」といった表現の方が理解され易いかもしれない。

# できること

ブラウザ上で人間が行う操作をプログラミングし「ブラウザ操作ロボット」を作ることで、Webアプリケーション開発時のテスト工数を節減できる。以下がメリットと考えています。

1. ボタン一つでテストが完了できる。（人間の作業が不要）
1. 異なるブラウザでのテストが可能。(つくりによるが大抵は再コーディング不要)
1. レガシーとなる。（費用の有効活用）

Webアプリケーション開発を行う際のテスト工数は開発費用として計上するわけですが、このテスト費用は凡そ「使い捨て」られがちなのではないでしょうか。Seleniumでテストシナリオを作成することで、その後も利用可能な「レガシー」となり得る。
<br/><img src="https://qiita-image-store.s3.amazonaws.com/0/237065/54e04d14-6efc-04f3-355f-e63292a72de0.png"><br/>※PCの中にロボット(Selenium)がいるイメージ。

# どう使うか（基本）
Selenium Webdriverと呼ばれるツールを利用します。任意のプログラミング言語(C#, Groovy, Java, Perl, PHP, Python, Ruby and Scala:by wikipedia)から、WebdriverのAPIを実行することでWebページの制御(文字入力やボタン押下等)を行うことができます。今回はJavaを利用した書き方を紹介します。以下の書き出しはIEを利用する際のお決まりのパターン。

```java
System.setProperty("webdriver.ie.driver", "./driver/32/IEDriverServer.exe");
WebDriver driver = new InternetExplorerDriver();
driver.manage().timeouts().implicitlyWait(120, TimeUnit.SECONDS);
```

実際の制御については、以下の構文にて行うことができます。

```java
driver.findElement(By.xpath("PATH_TO_TARGET")).OPERATION("PARAMETER");
```

この構文の意味は、"PATH_TO_TARGET"で制御対象の要素を特定し、要素が見つかったら"PARAMETER"で指定したパラメータを与え、".OPERATION"で指定する操作を行いなさい、という意味です。以下に"PARAMETER"と".OPERATION"の設定方法を説明します。

### PATH_TO_TARGETの指定
画面上での要素を制御するためには、「制御対象の要素がどこにあるか(位置)」を何らかのやり方で指定してあげねばなりません。画面上で「座標(x,y)」を指定するやり方が真っ先に思い浮かぶかもしれませんが、座標にしてしまうとディスプレイやウィンドウの大きさにより位置が異なったりするため、実行時に失敗してしまうケースが増える（実行時の精度が低い）懸念があります。そのため、Seleniumでは座標に依存しない正確な方法で要素を指定することができます。

<br/><img src="https://qiita-image-store.s3.amazonaws.com/0/237065/04171f95-c367-ad57-c546-0699851dcd66.png" width=80%><br/>例えば、yahooの検索ワード入力欄は上の画像のように、<html>タグから始まり、<input>タグにたどり着くわけですが、
<html>～<input>までのパスをxpathと呼びます。当該入力項目のxpathは以下のとおりとなります。
```
/html/body/div[1]/div[1]/div[3]/form/fieldset/div[1]/p/label/input
```
※今回は例としてXPathを掲載していますが、cssセレクタ等でも可。

### OPERATIONの指定
要素の特定方法が分かったところで、次にその要素に対して何のアクションを行うかを指定する必要があります(.OPRERATION部分)。主なものは先に記載しているとおり、クリックと文字列の入力です。

|操作         |OPERATION |
|:------------|:---------|
| クリック     | click    |
| 文字列の入力  | sendkeys |

以下はハイパーリンクをクリックするサンプル。

```java
driver.findElement(By.xpath("PATH_TO_TARGET")).click();
```

以下は入力項目に文字列を入力するサンプル。

```java
driver.findElement(By.xpath("PATH_TO_TARGET")).sendkeys("PARAMETER");
```

# 具体的な使い方
何らかのプログラミング言語を触ったことさえあれば誰でもできます。先ほど紹介した

```java
driver.findElement(By.xpath("PATH_TO_TARGET")).OPERATION("PARAMETER");
```

に当てはめて、自動化した処理を並べていくだけなので、非常に簡単です。制御したい画面中のコントロールにより若干書き方を変える必要がありますが、基本的には先にご紹介した２種類と、ドロップダウンリストボックスの制御方法（これも定石あり）さえ覚えておけば、7～8割の処理はカバーできるのではないかと思われます。

# 期待値との比較手段
手動（打鍵）テスト同様、基本的には与えたinputに対する結果の（合否）判定を行う必要があります。JUnit等のテスティングフレームワークを用いてテストケースを作成し、判定を行う手法が容易です。判定手法を２種類ご紹介します。

* inputに対する期待値の文字列とoutputを比較する
* inputに対する期待値の画像とoutput画像を比較する

### inputに対する期待値の文字列と比較する
こちらはスタンダードなやり方。inputに対して得られた結果を画面から拾い、予め準備した値とassertで比較します。JUnitの場合、判定結果がfalseとなり失敗してしまったテストケースが一目で分かります。

### inputに対する期待値の画像と比較する
Seleniumにはスクリーンショットを取得する機能もあり、これを利用して目的の画像を取得、期待値の画像と比較する方法です。文字列の場合と比較して一手間かかりますが、Webアプリケーションサーバのバージョンアップ、利用ブラウザのバージョンアップを行う際の回帰テスト等に有効な手段です。詳細なご紹介は割愛しますが、画像の比較についてはImageMagic等のソフトウェアを利用すれば容易且つ低廉に自動化することができます。

サンプルコードを作成中です。
https://github.com/knsquai/BrowserAutoTest

弊社では一緒にテスト自動化を推進してくれる仲間を募集しています。
https://www.nittsu-infosys.com/recruit/2019/index.html