Selenium/WebDriverとPage Object Patternを使ったテスト

Selenium / WebDriverとページオブジェクトパターンを使用したテスト

1. 前書き

この記事では、previous writeupに基づいて構築し、ページオブジェクトパターンを導入することでSelenium / WebDriverテストを引き続き改善します。

2. セレンを追加する

プロジェクトに新しい依存関係を追加して、よりシンプルで読みやすいアサーションを記述しましょう。


    org.hamcrest
    hamcrest-all
    1.3

最新バージョンはMaven Central Repositoryにあります。

2.1. 追加の方法

シリーズの最初のパートでは、ここでも使用するいくつかの追加のユーティリティメソッドを使用しました。

navigateTo(String url)メソッドから始めます。これは、アプリケーションのさまざまなページをナビゲートするのに役立ちます。

public void navigateTo(String url) {
    driver.navigate().to(url);
}

次に、clickElement(WebElement element)は、その名前が示すように、指定された要素に対してクリックアクションを実行します。

public void clickElement(WebElement element) {
    element.click();
}

3. ページオブジェクトパターン

Seleniumは、HTMLページとの対話に使用できる強力な低レベルAPIを多数提供します。

ただし、テストの複雑さが増すにつれて、DOMの低レベルの生の要素と対話することは理想的ではありません。 コードは変更が難しく、小さなUIの変更後に壊れる可能性があり、簡単に言えば柔軟性が低下します。

代わりに、単純なカプセル化を利用して、これらの低レベルの詳細をすべてページオブジェクトに移動できます。

最初のページのオブジェクトを書き始める前に、パターンを明確に理解しておくことをお勧めします。これにより、ユーザーとアプリケーションの相互作用をエミュレートできるようになります。

ページオブジェクトは一種のインターフェイスとして動作し、ページまたは要素の詳細をカプセル化し、その要素またはページとやり取りするための高レベルAPIを公開します。

そのため、重要な詳細は、メソッドにわかりやすい名前を付けることです(例: clickButton(), navigateTo())。ユーザーが実行したアクションを複製する方が簡単であり、通常、ステップを連鎖させるとAPIが向上します。

では、先に進みましょう。create our page object –この場合はホームページです。

public class exampleHomePage {

    private SeleniumConfig config;

    @FindBy(css=".header--menu > a")
    private WebElement title;

    @FindBy(css = ".menu-start-here > a")
    private WebElement startHere;

    // ...

    public StartHerePage clickOnStartHere() {
        config.clickElement(startHere);

        StartHerePage startHerePage = new StartHerePage(config);
        PageFactory.initElements(config.getDriver(), startHerePage);

        return startHerePage;
    }
}

実装がDOMの低レベルの詳細を処理し、優れた高レベルAPIを公開していることに注目してください。

たとえば、@FindByアノテーションを使用すると、WebElementsを事前入力できます。これは、ByAPIを使用して表すこともできます。

private WebElement title = By.cssSelector(".header--menu > a");

もちろん、両方とも有効ですが、注釈の使用は少し簡潔です。

また、チェーンに注意してください–clickOnStartHere()メソッドはStartHerePageオブジェクトを返します–ここで相互作用を続けることができます:

public class StartHerePage {

    // Includes a SeleniumConfig attribute

    @FindBy(css = ".page-title")
    private WebElement title;

    // constructor

    public String getPageTitle() {
        return title.getText();
    }
}

簡単なテストを書いてみましょう。ページに移動して、要素の1つを確認するだけです。

@Test
public void givenHomePage_whenNavigate_thenShouldBeInStartHere() {
    homePage.navigate();
    StartHerePage startHerePage = homePage.clickOnStartHere();

    assertThat(startHerePage.getPageTitle(), is("Start Here"));
}

当社のホームページには以下の責任があることを考慮することが重要です。

  1. 指定されたブラウザー構成に基づいて、ページに移動します。

  2. そこに来たら、ページのコンテンツ(この場合はタイトル)を検証します。

テストは非常に簡単です。ホームページに移動し、「ここから開始」要素をクリックして、同じ名前のページに移動します。最後に、タイトルが存在することを検証します。

テストの実行後、close()メソッドが実行され、ブラウザが自動的に閉じられます。

3.1. 懸念の分離

考慮に入れることができるもう1つの可能性は、関心の分離(さらに)である可能性があります。2つの別々のクラスを使用することで、ページのすべての属性(WebElementまたはBy)を処理します。

public class exampleAboutPage {

    @FindBy(css = ".page-header > h1")
    public static WebElement title;
}

もう一方は、テストする機能のすべての実装を処理します。

public class exampleAbout {

    private SeleniumConfig config;

    public exampleAbout(SeleniumConfig config) {
        this.config = config;
        PageFactory.initElements(config.getDriver(), exampleAboutPage.class);
    }

    // navigate and getTitle methods
}

属性をByとして使用していて、注釈機能を使用していない場合は、インスタンス化されないように、ページクラスにプライベートコンストラクターを追加することをお勧めします。

前の例でthisキーワードを渡したのとは対照的に、この場合はexampleAboutPageクラスのアノテーションを含むクラスを渡す必要があることに注意してください。

@Test
public void givenAboutPage_whenNavigate_thenTitleMatch() {
    about.navigateTo();

    assertThat(about.getPageTitle(), is("About example"));
}

実装内でページとやり取りするすべての内部詳細をどのように維持できるかに注目してください。ここでは、実際にこのクライアントを高い読み取り可能なレベルで使用できます。

4. 結論

このクイックチュートリアルでは、Selenium/WebDriver with the help of the Page-Object Patternの使用法の改善に焦点を当てました。 パターンを利用してサイトと対話する実際的な方法を確認するために、さまざまな例と実装を試しました。

いつものように、これらすべての例とスニペットの実装はover on GitHubにあります。 これはMavenベースのプロジェクトであるため、インポートと実行が簡単である必要があります。