サーチ…


前書き

WebサイトやWebアプリケーションを自動化する際に重要な役割を果たすのは、画面上の項目を特定し、それらと相互作用することです。項目は、ロケータとByクラスを使用してSeleniumで検出されます。これらのロケータとインタラクションは、コードの重複を避け、メンテナンスを容易にするためのベストプラクティスとして、Page Object内に配置されています。これは、 WebElementsをカプセル化し、ページ内(またはWebアプリケーション内のページの一部)でビヘイビアと情報を返すと仮定します。

備考

ページオブジェクトモデルは、Webページの特定のビューへのインタフェースとして機能するオブジェクト指向クラスを記述するパターンです。そのページクラスのメソッドを使用して、必要なアクションを実行します。数年前、私たちはテストクラスのWebページのHTMLコードを直接操作していましたが、これはUIの変更に脆弱で維持するのが非常に困難でした。

ただし、ページオブジェクトパターンの方法でコードを編成すると、アプリケーション固有のAPIが提供され、HTMLを掘り下げることなくページ要素を操作できるようになります。親指の基本的なRueによれば、あなたのページオブジェクトには、人間がそのWebページ上で行うことができるすべてがあるはずです。たとえば、Webページのテキストフィールドにアクセスするには、すべての変更を行った後にテキストを取得して文字列を返すメソッドが必要です。

ページオブジェクトを設計する際に留意すべき重要な点はほとんどありません。

  1. ページオブジェクトは、通常はページ用にのみ構築すべきではありませんが、ページの重要な要素用に構築することをお勧めします。たとえば、学問の異なる図表を表示する複数のタブを持つページは、タブの数と同じ数のページを持つ必要があります。

  2. あるビューから他のビューに移動すると、ページクラスのインスタンスが返されます。

  3. 特定のビューまたはWebページに対してのみ存在する必要があるユーティリティメソッドは、そのページクラスにのみ属している必要があります。

  4. アサーションメソッドはページクラスによって注意を払うべきではありません。ブール値を返すメソッドを持つことはできますが、そこでは検証しないでください。たとえば、ユーザーのフルネームを検証するには、ブール値を取得するメソッドを使用できます。

     public boolean hasDisplayedUserFullName (String userFullName) {
         return driver.findElement(By.xpath("xpathExpressionUsingFullName")).isDisplayed();
     }
    
  5. あなたのウェブページがiframeに基づいている場合は、iframeのページクラスも持つことをお勧めします。

ページオブジェクトパターンの利点:

  1. テストコードとページコードを明確に分離
  2. WebページのUIが変更された場合は、複数の場所でコードを変更する必要はありません。ページクラスでのみ変更します。
  3. 点在する要素ロケータはありません。
  4. コードを理解しやすくする
  5. 簡単なメンテナンス

はじめに(Javaの使用)

Pageオブジェクトパターンに基づいてログインテストを実行する例:

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

/**
 * Class which models the view of Sign-In page
 */
public class SignInPage {
    
    @FindBy(id="username")
    private usernameInput;

    @FindBy(id="password")
    private passwordInput;

    @FindBy(id="signin")
    private signInButton;

    private WebDriver driver;

    public SignInPage(WebDriver driver) {
        this.driver = driver;
    }
    
    /**
     * Method to perform login
     */
    public HomePage performLogin(String username, String password) {
        usernameInput.sendKeys(username);
        passwordInput.sendKeys(password);
        signInButton.click();
        return PageFactory.initElements(driver, HomePage.class);
    }
}


import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
/**
 * Class which models the view of home page
 */
public class HomePage {
    @FindBy(id="logout")
    private logoutLink;

    private WebDriver driver;

    public HomePage(WebDriver driver) {
        this.driver = driver;
    }
    
    /**
     * Method to log out
     */
    public SignInPage logout() {
        logoutLink.click();
        wait.ForPageToLoad();
        return PageFactory.initElements(driver, SignInPage.class);
    }
}

/**
 * Login test class
 */
public class LoginTest {
    public void testLogin() {
        SignInPage signInPage = new SignInPage(driver);
        HomePage homePage = signInPage.login(username, password);
        signInPage = homePage.logout();
    }
}

C#

ページオブジェクトには、動作、アサーションの情報を返す必要があり、場合によっては初期化時のページレディステートメソッドのメソッドを含める必要があります。 Seleniumは、注釈を使用してページオブジェクトをサポートしています。 C#では次のようになります:

using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
using OpenQA.Selenium.Support.UI;
using System;
using System.Collections.Generic;

public class WikipediaHomePage
{
    private IWebDriver driver;
    private int timeout = 10;
    private By pageLoadedElement = By.ClassName("central-featured-logo");

    [FindsBy(How = How.Id, Using = "searchInput")]
    [CacheLookup]
    private IWebElement searchInput;

    [FindsBy(How = How.CssSelector, Using = ".pure-button.pure-button-primary-progressive")]
    [CacheLookup]
    private IWebElement searchButton;

    public ResultsPage Search(string query) 
    {
        searchInput.SendKeys(query);
        searchButton.Click();
    }

    public WikipediaHomePage VerifyPageLoaded() 
    {
        new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)).Until<bool>((drv) =>  return drv.ExpectedConditions.ElementExists(pageLoadedElement));

        return this;
    }
}

ノート:

  • CacheLookupは、キャッシュに要素を保存し、各呼び出しごとに新しい要素を戻して保存します。これによりパフォーマンスは向上しますが、動的に変化する要素には適していません。
  • searchButtonは2つのクラス名とIDはありません。そのため、クラス名やIDは使用できません。
  • デベロッパーツール(Chrome用)、FireBugなどを使用できる他のブラウザーでロケーターが私に返す要素があることを確認しました。
  • Search()クリックは別のページにリダイレクトされるので、 Search()メソッドは別のページオブジェクト( ResultsPage )を返します。

ベストプラクティスページオブジェクトモデル

  • ヘッダーとフッター用に別々のファイルを作成します(すべてのページに共通であり、1ページの一部にするのは意味がありません)
  • 共通の要素(検索/戻る/次のように)を別々のファイルに保存します(アイデアはあらゆる種類の複製を削除し、分離を論理的に保つことです)
  • Driverについては、別のDriverクラスを作成してDriverを静的にして、すべてのページにアクセスできるようにすることをお勧めします。 (私のすべてのWebページでDriverClassが拡張されています)
  • PageObjectsで使用されている関数は、周波数とそれが呼び出される方法を念頭に置いてできる限り小さなチャンクに分割されています(ログインはenterUsername関数とenterPassword関数に分解されますが、多くの場合、enterUsername関数とenterPassword関数への呼び出しを分離するのではなく、Login関数が呼び出されるため、Login関数はより論理的です)
  • PageObjectsを使用すると、elementLocatorsからTestスクリプトが分離されます。
  • 別のutilsフォルダ(例えば、DateUtil、excelUtilsなど)でユーティリティ機能を使用する
  • 別のconfフォルダに設定する(テストの実行環境の設定、出力フォルダと入力フォルダの設定など)
  • 失敗時にscreenCaptureを組み込む
  • DriverClassに静的な待機変数をいくつかの暗黙的な待機時間を置いたようにしてください。常にwait.until(ExpectedConditions)のような静的な待機ではなく、条件付きの待機を試行してください。これにより、待機が実行を不必要に遅くしていないことが保証されます。


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow