以下記事の続きです。
Selenide~Javaで超簡単・簡潔にUIテストを書く~
http://qiita.com/tatesuke/items/589e30ab9b3dc7037e26
SelenideではPageオブジェクトパターンを利用することを薦められているようです。
なんだか仰々しい感じがしますが、
1つのページを1つのオブジェクトとして表現しよう
ということです。つまり
/* 検索ページ */
open("/login");
//"selenide"で検索
$(By.name("q")).setValue("selenide").pressEnter();
/* 検索結果ページ */
// 検索結果が10件あること
$$("#ires li.g").shouldHave(size(10));
// 先頭の結果がSelenideのページであること。
$$("#ires li.g").get(0).shouldHave(text("Selenide: Concise UI Tests in Java"));
のようにテストコードでロケータを使うのではなく、
// テストコード
GoogleSearchPage searchPage = open("/login", GoogleSearchPage.class);
GoogleResultsPage resultsPage = searchPage.search("selenide");
resultsPage.results().shouldHave(size(10));
resultsPage.results().get(0).shouldHave(text("Selenide: Concise UI Tests in Java"));
-------
// 検索ページのPageオブジェクト
public class GoogleSearchPage {
public GoogleResultsPage search(String query) {
$(By.name("q")).setValue(query).pressEnter();
return page(GoogleResultsPage.class);
}
}
// 検索結果ページのPageオブジェクト
public class GoogleResultsPage {
public ElementsCollection results() {
return $$("#ires li.g");
}
}
のように、ページごとにオブジェクトを作り、そのオブジェクト経由でテストを実施しましょうということです。
見ての通りPageオブジェクトは単なるPOJOで、open
メソッドの第二引数にclassを渡して生成します。
これの利点は以下です。
- テストコードからロケータが消える
→ページの構造や処理をPageオブジェクトに隠す(カプセル化)ことでテストコードはテストに専念できる - Pageオブジェクトを複数テストで使いまわすことができる。
SelenideのPageオブジェクトサポート
フィールドが多いフォームだと、Pageオブジェクトのなかで大量のロケータを記述する必要がでてきます。
そこでSelenideでは、以下のように@FindBy
アノテーションを使ってフィールドを宣言するだけでPageオブジェクトとHTMLのフィールドを関連付けることができるようになっています。
public class GoogleSearchPage {
@FindBy(how = How.NAME, using = "q")
private SelenideElement searchBox;
public GoogleResultsPage search(String query) {
searchBox.setValue(query).pressEnter();
return page(GoogleResultsPage.class);
}
}
public class GoogleResultsPage {
@FindBy(how = How.CSS, using = "#ires li.g")
public ElementsCollection results;
}
当然ながら単純にnew
をしてしまっては関連付けはされません。open
メソッドやpage
メソッド経由でインスタンス化してください。
まとめ
Pageオブジェクトをつかってテストコードからセレクタを追い出しましょう。