以下記事の続きです。
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オブジェクトをつかってテストコードからセレクタを追い出しましょう。