はじめに
注意事項
- 私は、Seleniumを使ってテストコードは書いていません。
前提知識
- HTMLの基礎
- CSSセレクタ
参考図書
目次
- Seleniumの概要
- Sleniumを動かしてみる
- Seleniumでできること
- Selenium IDE
1. Seleniumの概要
Seleniumとは
- Webアプリケーションの画面操作を自動化するツール。
- 主に画面テストの自動化に使われる
- テスト以外にも使われる
- 大量のデータの登録などの単純作業
- Webスクレイピング
Selenium automates browsers. That's it!
※ http://www.seleniumhq.org/ 引用
Seleniumを構成する主なツール
Seleniumはツールの集合体。単体のツールではない。
-
Selenium WebDriver(以下、WebDriver)
- Java, Ruby, JavaScriptなどのプログラミング言語から、ブラウザ操作が可能
- 本格的なテスト自動化に適している
(コードの共通化などによるメンテナンスコスト削減が可能なので)
-
Selenium IDE
- ブラウザ操作を記録して再生できるFirefoxのアドオン
- Seleniumの体験に適している
- 本格的な運用には適していない
※ Selenium Project 引用
Seleniumがサポートしている主なプラットフォーム
- ブラウザ
- Firefox
- Chrome
- Internet Explore
- Microsoft Edge
- PhantomJS(後述)
- OS
- WIndows
- Mac OS X
- Linux
- プログラミング言語
- Java
- C#
- Python
- JavaScript
- Python
- Ruby
※ Platforms Supported by Selenium 参考
2. Seleniumを動かしてみる
テスト対象のサイト
<input type="text" id="inputX"> + <input type="text" id="inputY">
= <input type="text" id="result" readonly>
<br>
<button type="button" id="calculate" onclick="calculate();">Calculate</button>
function calculate() {
var result = Number(document.getElementById("inputX").value) + Number(document.getElementById("inputY").value);
document.getElementById("result").value = result;
}
実行環境の構築
- Selenium 3.4.0
- JUnit 4.12
- Firefox 54.0
-
geckodriver v0.18.0
- Firefox用のドライバ
- exeファイルを適当のフォルダに配置
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
Seleniumを使ったテストコード
public class SampleTest {
WebDriver driver;
@Before
public void setUp() throws Exception{
//geckodriver.exeのパスを設定
System.setProperty("webdriver.gecko.driver", "/tmp/geckodriver.exe");
//Firefox起動
driver = new FirefoxDriver();
//画面遷移
driver.get("file:///C:/tmp/sample.html");
}
@Test
public void 入力値が1と2のときの加算結果が表示される() {
//テキストボックスに"1"を入力する
WebElement xElm = driver.findElement(By.id("inputX"));
xElm.clear();
xElm.sendKeys("1");
//テキストボックスに"2"を入力する
WebElement yElm = driver.findElement(By.id("inputY"));
yElm.clear();
yElm.sendKeys("2");
//ボタンを押す
driver.findElement(By.id("calculate")).click();
//計算結果用のテキストボックスのvalue属性値を取得
String actual = driver.findElement(By.id("result")).getAttribute("value");
String expected = "3";
//期待結果の比較
assertThat(actual, is(expected));
}
@After
public void tearDown() throws Exception{
driver.quit();
}
}
3. Seleniumでできること
Selenium WebDriverの仕組み
※ https://app.codegrid.net/entry/selenium-1 引用
WebDriverでできること part1
- 要素の取得
- ID属性の値
- CSSセレクタ記法
- XPath記法
- 要素の操作
- URL遷移
- クリック
- キー入力
- チェックボックス、ラジオボタン、プルダウンの選択
- subnit
- 要素情報の取得
- 表示・非表示
- 有効・無効
- 存在するかどうか
- 選択状態
- 属性、テキスト、タグ名
- CSSプロパティ
- サイズ、位置
- ブラウザ情報の取得
- タイトル、URL
- HTMLソース
- ウィンドウ位置、ウィンドウサイズ
- Cookie
※ 『Selenium 実践入門』4.3~4.6章 参考
※ Selenium Web Driver 参考
WebDriverでできること part2
- 画面キャプチャ
- ブラウザの種類によって、スクロール範囲外が含まれるかどうかが変わる
※ Seleniumのスクリーンショットはどうやって撮っているのだろう 参照
- ブラウザの種類によって、スクロール範囲外が含まれるかどうかが変わる
- JavaScriptの実行
- ブラウザの戻る、進む
- 待ち処理
- Alert, Cnfirm, Promptダイアログの操作
- Safari, PahntomJsのドライバでは操作できないらしい(未確認)
- ダイアログが表示された状態の画面キャプチャは取得できない
- ウィンドウの操作
- フレームの操作
- マウス・キーボード操作
- ダブルクリック、右クリック
- マウスの移動、ドラッグ&ドロップ
- キーを押しながらクリック
※ 『Selenium 実践入門』4.7~4.10章 参考
WebDriverでできないけど、工夫すればなんとかできること
-
ファイルアップロードダイアログ
- ダイアログを直接操作できない
- 対応案: input要素に
sendKey
メソッドで直接パスを入力する
-
ファイルダウンロード
- ダイアログを直接操作できない
- 対応案1:ブラウザ設定で、ダウンロードダイアログを非表示にする
- 対応案2:ブラウザ設定で、ダウンロードディレクトリを指定する
- InternetExploreDirverでは確認ダイアログを非表示にできない(未確認)
-
新しいtypeのinput要素(HTML5から導入)
- typeが日付・時刻
- typeがrange
- typeがcolor
- 対応案:JavaScriptでvalue属性の値を設定する
※ 『Selenium 実践入門』5章 参考
[私見] WebDriverのできる/できないの勘所
- JavaScriptができることは、WebDriverもできる
- ブラウザごとに動きやレイアウトが異なる機能は、できない場合がある
- ダイアログなど
- セキュリティの観点で制限がある機能は、できない場合がある
- ファイル操作
4. Selenium IDE
[Try] Selenium IDEの操作
- 記録の開始
- テストの再生
- 速度調整
- テストケースの保存
- HTMLファイル
- プログラミング言語へのエクスポート
Selenium IDEの特徴
- ブラウザ操作を記録して再生できるFirefoxのアドオン
- テストコードがHTMLファイルのため自由度が低い
- if文やfor文が書きにくい(書くことは可能)
- 古いSeleniumがベースになっているので、WebDriverよりできることが少ない
[補足] Selenium Builder
- Selenium IDEの後継ツール
- WebDriverをベースにしているので、Selenium IDEよりできることが多い
- Selenium IDEより使いづらい
Selenium IDEの要素取得(locator)
- locatorの優先度(ID, css, xpathなど)は、設定で変更できる
- ID属性がない要素のlocatorは読みにくい
- たとえば、以下のボタン操作を記録した場合、2個目のボタンはXPATHを使ったlocatorになる
<!-- locaitor: css="button.sample" -->
<button class="sample" >sample</button>
<!-- locator: css="button.sample" -->
<button class="sample" >sample</button>
[私見] Selenium IDEでテスト自動化を行うべきか?
-
Selenium IDEのコード(HTMLファイル)で自動化するのは、非現実的
- 共通化が難しい
- クロスブラウザテストが難しい(できなくはなない)
-
Selenium IDEのコードからエクスポートしたWebDriverのコードで、テスト自動化した方がよさそう。上記の問題は解決できる。
-
間違った操作も記録されるが、それを修正するのが面倒。
-
WebDriverに慣れたら、Selenium IDEで記録するより、直接WebDriverでコードを書いた方が、生産性が良さそう
付録
ページオブジェクトパターン
- メンテナンス性の高いコードを作成する共通化技法
- テスト対象の画面情報を共通クラスに集約
- 画面構成の修正に伴う修正コストを削減
ページオブジェクトパターンのサンプル
- 以下のソースはページオブジェクトパターンで書いたコード。たとえば、ボタンのID属性値"calculate"が変わっても、テストコードは1か所を変えるだけでよい。
public class CalculatePage {
private WebDriver driver;
public CalculatePage(WebDriver driver) {
this.driver = driver;
}
/** 計算ボタン */
@FindBy(id = "calculate")
private WebElement calculateButton;
/** 計算ボタンを押す */
public void calculate() {
calculateButton.click();
}
}
Selenium関連のライブラリ
WebDriverのコマンドは冗長
-
Geb
- Groovy言語(Java言語の拡張)で簡潔に記述できる
- jQuery記法に近い記述で、要素を取得できる
-
Fluentlenium
- Javaで簡潔に記述できる
- jQuery記法に近い記述で、要素を取得できる
- Page Object Patternを支援する機能を持つ
私はFluentleniumを使っている。
//WebDriverの記述
driver.findElement(By.id("calculate")).click();
//Fluentleniumの記述
$("calculated").click();
PhantomJS
- ヘッダレスブラウザ
- UIを持たないブラウザ
- 高速に動作する
WebDriverはテスト用の機能がない
期待結果の検証はJunitを使っているが、JUnitでなくてもよい。
テスト自動化の参考サイト
Selenium以外のWebテストツール
他のツールと比較したSeleniumの特徴
- 無料でオープンソース
- サポートしているブラウザが多い
その他の感想
- IE実行の環境設定が面倒。そしてハマりやすい。
- レジストリの設定が必要
- ズームを100%にしないとエラー
- 「保護モード」を考慮する必要あり
- SeleniumでInternet Explorer11を動かす方法 参考
Seleniumを使う際の工夫
-
要素の取得や結果の比較には、できるだけ変更されにくい値(IDやname属性値など)をを、参照すること
-
「JavaScriptのエラーがないこと」を確認するのは簡単なので、テストコードに組み込んだ方がよさそう