Page Object Patternで保守性の高いUIテストコードを書こう!【Selenide】

3 min

概要

PageObjectデザインパターンとは、アプリケーションの画面を1つのオブジェクトとしてとらえるデザインパターンの1種。
重複したコードを減らすことで、UI変更にも強い保守性の高いテストコードの書き方。

Seleniumのサイトには以下のように概要が紹介されている。

Summary
– The public methods represent the services that the page offers
– Try not to expose the internals of the page
– Generally don’t make assertions
– Methods return other PageObjects
– Need not represent an entire page
– Different results for the same action are modelled as different methods

簡単に訳していくと以下の通り

  • パブリックメソッドでそのページが提供するサービスを表現してね
  • ページの内部を公開しちゃだめよ
  • 一般的にアサーションすることは禁止だよ
  • メソッドはPageObjectを返却するよ
  • ページ全体を表現する必要はないよ、つまり必要な部分だけつくればOK
  • 同じアクションでも、違う結果になる場合は別のメソッドを定義してね

先日紹介したSelenideとも相性がよく、公式でもページオブジェクトパターンで実装することが推奨されています。Selenideについてはこちらを見てみてくださいね。

実装方針

実装に際して以下に注意しましょう!

  • 1ページ1オブジェクト
  • アサーションは行わない
  • メソッドはPageObjectを返却する
  • テストに必要な部分のみ実装する

それではページオブジェクトパターンでSeleniumのラッパーであるSelenideを使って実装例を書いていきましょう!

Page Objectの実装例

実装例ではトップページ→ユーザ登録ページ→ユーザ登録確認ページの3つのページから成るWebシステムを例にあげて、3つのページオブジェクトクラスを作成しています。

トップページ

public class TopPage {

  public TopPage login(String userID, String password) {
    $(byId("headerCustomerNo")).setValue(userID);
    $(byId("headerPassword")).setValue(password);
    $(".button").click();
    return this;
  }

  public UserRegisterPage toUserRegisterPage() {
    $(byLinkText("ユーザ情報登録")).click();
    return new UserRegisterPage();
  }

  public UserDetailPage toUserDetailPage() {
    $(byLinkText("ユーザ情報管理")).click();
    return new UserDetailPage();
  }
}

ユーザ登録ページ

public class UserRegisterPage {

  public UserRegisterPage setMemberInfo(MemberBean member, String imagePath) {
    // 会員情報入力処理
    return this;
  }

  public UserRegisterConfimPage toRegisterConfirmPage() {
    $(".forward").click();
    return new UserRegisterConfimPage();
  }
}

ユーザ登録確認ページ

public class UserRegisterConfimPage {

  public UserRegisterCompletePage registerUser() {
    $(".forward").click();
    return new UserRegisterCompletePage();
  }
}

Test Caseの実装例

見よ!!このシンプルさを!!

public void userRegisterTest() {

//事前準備
// omitted

// テスト実行
open(applicationContextUrl, TopPage.class)
.toUserRegisterPage()
.setMemberInfo(member, imagePath)
.toRegisterConfirmPage()
.registerUser();
}

ページオブジェクトパターンのメリット

メソッドチェーンを使用し、テストのシナリオの可読性を向上

画面遷移のある場合は遷移先のPageObjectを返却し、遷移が発生しない場合は自身のPageObjectを返却(this)する。
これにより、メソッドチェーンを使用し、テストのシナリオの可読性を向上させることができる。

画面などに変更があった場合でも対応しやすく保守性が高い

画面の変更が行われた場合、テストケース内に処理を羅列する方法では修正範囲がかなり大きくなることが予想されるが、PageObjectsPatternを採用していれば、変更のあった画面のオブジェクトのみを変更すればよく、修正を最小限に抑えることができる。

とっつきづらいかもしれませんが、かなりテストコードが書きやすく、読みやすくなるので、ぜひトライしてみてください!