SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

WebDriverの採用で生まれ変わったOSSのブラウザテストツール「Selenium 2」入門

実践! PageObjectパターンによる「Selenium2」テストケース改善チュートリアル

WebDriverの採用で生まれ変わったOSSのブラウザテストツール「Selenium2」入門 第4回

  • X ポスト
  • このエントリーをはてなブックマークに追加

5.2. LoginPage

 まず、ログイン画面を表すPageObjectを下記のように作成します。

LoginPage.java
package com.example.pages;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class LoginPage { // 

    private final WebDriver driver;

    @FindBy(name = "username") // 
    @CacheLookup // 
    private WebElement username;

    @FindBy(name = "password")
    @CacheLookup
    private WebElement password;

    @FindBy(xpath = "//button[@type='submit']")
    @CacheLookup
    private WebElement loginButton;

    public LoginPage(WebDriver driver) { // 
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    public LoginPage open(String baseUrl) {
        driver.get(baseUrl + "/login/index");
        return this;
    }

    public LoginPage typeUsername(String key) { // 
        username.sendKeys(key);
        return this;
    }

    public LoginPage typePassword(String key) {
        password.sendKeys(key);
        return this;
    }

    public HomePage submitLoginExpectingSuccess() { // 
        loginButton.click();
        return new HomePage(driver);
    }

    public LoginPage submitLoginExpectingFailure() { // 
        loginButton.click();
        return new LoginPage(driver);
    }
}

 はじめに、のとおりログイン画面を表すクラスを宣言します。特定のクラスを継承したり、インターフェースを実装する必要はありません。

 ログイン画面上の要素は、のように指定します。@FindByアノテーションには、nameやxpath属性の他に、idやcssなど、By.findElementと同程度のものを指定することができます。詳細はJavaDocを参照してください。

 は、構築したWebElementをキャッシュする指定です。このアノテーションがない場合、ログイン画面にアクセスするたびにWebElementを構築するので、パフォーマンスが落ちてしまいます。サンプルアプリケーションの画面要素は常に同じなので、このアノテーションを指定しましたが、JavaScriptでDOMを書き換えるような画面の場合は、このアノテーションを指定すると期待通りにテストが動作しないので注意してください。

 は、このPageObjectを初期化するコンストラクタです。PageFactory.initElement()を実行しないと、WebElementが初期化されず、後続の処理でNullPointerExceptionが発生してしまうので、注意してください。

 ログイン画面上の機能は、以降のように宣言します。ここではユーザー名を入力する機能などをメソッドとして宣言しています。どの機能をどの程度の細かさで宣言するかは、テスト次第です。あまり難しく考えずに、必要になった時点で追加していけばよいでしょう。

 はログインに成功した場合の振る舞いを表現するメソッドです。ログインに成功した場合はホーム画面に遷移するので、ホーム画面を表すHomePageクラスを返却します。一方、ログインに失敗した場合はログイン画面に遷移するので、⑦のようにLoginPageクラスを返却する別のメソッドとして宣言します。

5.3. HomePage

 同じようにして、ホーム画面を表すPageObjectを作成します。

HomePage.java
package com.example.pages;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class HomePage {

    private final WebDriver driver;

    @FindBy(linkText = "Logout")
    @CacheLookup
    private WebElement logoutLink;

    public HomePage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    public LoginPage logout() {
        logoutLink.click();
        return new LoginPage(driver);
    }
}

 特に難しいところはないと思います。ログアウト用のアンカーがあり、これをクリックするとログイン画面に遷移します。

5.4. 改善したテストケース

 最後に、これらのPageObjectを使って、変更後の仕様に対応するようテストケースを修正しましょう。ここでは、ユーザー名に「username」、パスワードに「password」を入力するとログインできるものとします。

SampleTest.java
// 省略
public class SampleTest {
// 省略
    @Before
    public void setUp() throws Exception {
        driver = new FirefoxDriver();
        baseUrl = "http://se2sample2.herokuapp.com/";
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
    }

    @Test
    public void testSample() throws Exception {

        LoginPage loginPage = new LoginPage(driver);

        loginPage.open(baseUrl);
        loginPage.typeUsername("username");
        loginPage.typePassword("badpassword");
        loginPage = loginPage.submitLoginExpectingFailure();
        assertEquals("Login", driver.getTitle());

        loginPage.typeUsername("username");
        loginPage.typePassword("password");
        HomePage homePage = loginPage.submitLoginExpectingSuccess();
        assertEquals("Home", driver.getTitle());

        loginPage = homePage.logout();
        assertEquals("Login", driver.getTitle());
    }
// 省略
}

 仕様変更対応後のサンプルアプリケーションを参照するよう、baseUrlの値を変更してあるので注意してください。

 画面仕様と強く結びついたコードが排除され、仕様変更に強いテストケースに改善されたことが分かると思います。

 修正が完了したら、JUnitテストケースとして実行して、引き続きテストが成功することを確認してください。

次のページ
6. PageObjectパターンによる型安全なテストケース

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
WebDriverの採用で生まれ変わったOSSのブラウザテストツール「Selenium 2」入門連載記事一覧

もっと読む

この記事の著者

梅澤 雄一郎(株式会社DTS)(ウメザワ ユウイチロウ)

株式会社DTS 産業事業部所属。playframeworkドキュメント翻訳サイト 管理人。主にJavaによるWebアプリケーション開発に従事。酒好き。 はてなブログ ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7527 2013/12/13 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング