結論seleniumの違い
- seleniumは本来UI自動テストツールではなく自動ブラウザ操作のためのツール
- selenideはUI自動テストが主目的のツール
selenideの特徴
WebDriverを直接操作しない
Seleniumでは画面を開いたり、要素を探したりするのにWebDriverを直接操作する必要がありました。
しかし、SelenideではWebDriverをフレームワークで隠蔽しており、使用者がSelenideの単純なメソッドを呼び出すだけで
各操作を実現できるようになっています。
Ajaxのサポート
Ajaxを使用しているアプリを操作するためには、各操作ごとに待機時間が必要です。
Seleniumでは、各操作をするごとに使用者がwaitを記述しないといけませんでしたが、Selenideではフレームワークが自動で待機してくれます。
デフォルトでは、最大4秒間待機するようになっています。
ただし、これはすべてのアクションで毎回4秒待機するというわけではなく、
Selenideで指定された要素が存在しない場合現れるまで4秒待機してみるというロジックになっています。
- selenideはseleniumのラッパー
「ソフトウェアやプログラム部品などが提供するクラスや関数、データ型などを、本来とは異なる環境や方法で利用できるようにしたものをラッパーという」
やるべきことが明快
Three simple thigsを掲げており、
すべてはコレの繰り返しor組み合わせで実装すればよい。
// Open the page
$(element).doAction()
$(element).check(condition)
何が返ってくるのかわかりやすい
たとえば、要素の選択でつかう、$()と$$()だと…
SelenideElement elm1 = $("#btn");→要素1つ(複数の場合は先頭)
$(".forward", 1).click(); →第二引数にintを渡すと先頭以外も指定できる
ElementsCollection elms1 = $$(".btn");→要素の集合
要素の指定が簡単
基本的に$もしくは、$$で要素の指定を行う。
最も使うのは$(java.lang.String cssSelector)
で、指定が難しい場合$(org.openqa.selenium.By seleniumSelector)
で指定できる。
また、org.openqa.selenium.By
を生成するSelectorsクラスがあり、これらを使用することで、可読性をあげることができる。
$(“親要素“).$(“子要素“)と範囲を絞ることで指定がすることができる。
例:$(byId("vacantflightlist")).$("tr", 1).$(byName("select"), 1).click();
→ xPathと比べて、書人も読む人も分かり易い これ重要!
アサーションメソッドが用意されている
$("div").shouldHave(text("Hello world!")); 等々。
デフォルトで4秒間100ミリ秒間隔でリトライするので明示的にwaitを書く必要がない。
※遷移してないのにしたと認識してしまう場合があるので、ところどころ下記で対応した。
$(".dep_date_td").waitUntil(not(text(baseDate)), 2000);
shoud~~に渡すConditionは多数用意されている。
- text(String)
- value(String)
- visible
- selected
- enable
- empty
- exist
etc..
テストに失敗すると、自動で証跡(png&html)が保存される。
screenshot("fileName");で撮ることも可能
Page Objectパターンとは?
Page Objectパターンとは自動テストでよく用いられる手法の一つで、対象画面毎にクラスを作成し、
その画面固有の操作/要素について定義する方法です。Seleniumのサイトでも説明されています。この手法では以下のようなメリットが生まれます。
- 処理の重複を避ける
- 画面レイアウト変更などにより要素取得方法が変更になっても、テスト自体への影響を局所化できる
- 要素取得の実装をテスト記述側で意識しなくてすむ
- 実装方法によっては、テスト記述でSelenium固有のAPIを意識せずにすむ
Javaで簡単にUIテストを書けるSelenideを使おう~Selenideの概要とテストの保守性を上げるPage Objectパターンの紹介
拡張・修正のポイント
- ページデザイン変更時の対応
- 複数画面で共通している部分の対応
ページデザイン変更時の対応
よくあるケースは、テストを実装した後に画面デザインが変更され、要素の位置なども変わる場合
IDで取得している部分はIDが変更されない限りはそれまで通りで動くが、それ以外については大抵修正が必要となる。
Page Objectを使用しているとテストシナリオは修正する必要がなく、Page Objectのうち要素取得のみを記述したAbstract Classのみの修正で対応が可能。
複数画面で共通している部分の対応
常にメニューが表示されている場合にはPage Objectを使用しても重複が発生してしまいます。
共通なものはどこか一か所で定義したい場合は、共通の親クラスを作りそこに定義するという方法もあるが、
Javaでは多重継承は許されていないため、共通要素が複数あり、それが画面によってあったり無かったりということだと対応しきれません。
このような場合は、Java 8で導入されたInterfaceのdefault methodを使う。
理由
Interfaceは一つのClassに複数implementできます。
ただし、default methodは可視性がpublicしか指定できないため、要素取得と振る舞いの分離が完全にできない
Java 9ではdefault methodにpublic以外の可視性でメソッドが定義できるようですが、
Java 8ではdefault methodでは共通部分の振る舞いを定義したPage Objectを返すようにすることで対応可能
まとめ
Seleniumをそのまま使うのと比べてかなり書きやすく、可読性も高いのが特徴。
PageObjectPatternと組み合わせることで更に可読性を上げることができる。