ページ オブジェクト モデル (POM) とページ ファクトリ Selenium
ページオブジェクトモデルとは何ですか?
ページ オブジェクト モデル (POM) は、Web UI 要素のオブジェクト リポジトリを作成するテスト自動化でよく使用されるデザイン パターンです。 このモデルの利点は、コードの重複が減り、テストのメンテナンスが改善されることです。
このモデルでは、アプリケーション内の各 Web ページには、対応する Page クラスが必要です。このページ クラスは、その Web ページの Web 要素を識別し、それらの Web 要素に対して操作を実行する Page メソッドも含みます。これらのメソッドの名前は、実行しているタスクに応じて指定する必要があります。たとえば、ローダーが支払いゲートウェイの表示を待機している場合、POM メソッド名は waitForPaymentScreenDisplay() になります。
なぜページオブジェクトモデルを使うのか?
で UI オートメーションを開始する Selenium WebDriver は難しい作業ではありません。要素を見つけて、それに対して操作を実行するだけです。
Web サイトにログインするための次の単純なスクリプトを考えてみましょう。
ご覧のとおり、私たちが行っているのは要素を見つけて、それらの要素に値を入力することだけです。
これは小さなスクリプトです。 スクリプトのメンテナンスは簡単そうです。 しかし、時間の経過とともにテストスイートは拡大します。 コードに行を追加すると、作業が難しくなります。
スクリプトのメンテナンスに関する主な問題は、10 個の異なるスクリプトが同じページ要素を使用しており、その要素を変更すると、10 個のスクリプトすべてを変更する必要があることです。 これには時間がかかり、エラーが発生しやすくなります。
スクリプトを保守するためのより良いアプローチは、Web 要素を検索し、それらに入力または検証する別のクラス ファイルを作成することです。 このクラスは、その要素を使用するすべてのスクリプトで再利用できます。 将来、Web 要素に変更があった場合、1 個の異なるスクリプトではなく、10 つのクラス ファイルのみで変更を加える必要があります。
このアプローチは、以下ではページ オブジェクト モデルと呼ばれます。 Seleniumコードの可読性、保守性、再利用性が向上します。
POMのメリット
- ページ オブジェクト デザイン パターンでは、UI の操作とフローは検証から分離する必要があるとされています。この概念により、コードがよりクリーンでわかりやすくなります。
- 2 番目の利点は、オブジェクト リポジトリがテスト ケースから独立しているため、同じオブジェクト リポジトリを異なるツールで異なる目的に使用できることです。たとえば、ページ オブジェクト モデルを次のように統合できます。 Selenium TestNG/JUnit 機能のため テスト そして同時にJBehave/Cucumber 受け入れテスト用。
- POM クラスのページ メソッドが再利用できるため、コードが少なくなり、最適化されます。
- メソッドには、UI で発生する操作に簡単にマッピングできる、より現実的な名前が付けられます。たとえば、ボタンをクリックした後にホームページに移動する場合、メソッド名は「gotoHomePage()」のようになります。
POM を実装するにはどうすればよいですか?
シンプルな POM:
これは、ページ オブジェクト モデル フレームワークの基本構造であり、 AUT これらの Web 要素を操作するメソッドはクラス ファイル内で管理されます。検証などのタスクは、テスト メソッドの一部として分離する必要があります。
完全な例
テストケース: Guru99 デモ サイトにアクセスします。
ステップ 1) Guru99 デモサイトにアクセスします
ステップ 2) ホームページに「Guru99 Bank」というテキストが存在することを確認します。
ステップ 3) アプリケーションにログインする
ステップ 4) ホームページに「マネージャー ID: デモ」というテキストが含まれていることを確認します。
ここでは 2 ページを扱います
- ログインページ
- ホームページ (ログインすると表示されます)
したがって、2つのPOMを作成します。 Selenium クラス
Guru99 ログインページ POM
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class Guru99Login { WebDriver driver; By user99GuruName = By.name("uid"); By password99Guru = By.name("password"); By titleText =By.className("barone"); By login = By.name("btnLogin"); public Guru99Login(WebDriver driver){ this.driver = driver; } //Set user name in textbox public void setUserName(String strUserName){ driver.findElement(user99GuruName).sendKeys(strUserName); } //Set password in password textbox public void setPassword(String strPassword){ driver.findElement(password99Guru).sendKeys(strPassword); } //Click on login button public void clickLogin(){ driver.findElement(login).click(); } //Get the title of Login Page public String getLoginTitle(){ return driver.findElement(titleText).getText(); } /** * This POM method will be exposed in test case to login in the application * @param strUserName * @param strPasword * @return */ public void loginToGuru99(String strUserName,String strPasword){ //Fill user name this.setUserName(strUserName); //Fill password this.setPassword(strPasword); //Click Login button this.clickLogin(); } }
Guru99 ホームページ POM で Selenium
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class Guru99HomePage { WebDriver driver; By homePageUserName = By.xpath("//table//tr[@class='heading3']"); public Guru99HomePage(WebDriver driver){ this.driver = driver; } //Get the User name from Home Page public String getHomePageDashboardUserName(){ return driver.findElement(homePageUserName).getText(); } }
Guru99 シンプル POM で Selenium テストケース
package test; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import pages.Guru99HomePage; import pages.Guru99Login; public class Test99GuruLogin { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; Guru99Login objLogin; Guru99HomePage objHomePage; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("http://demo.guru99.com/V4/"); } /** * This test case will login in http://demo.guru99.com/V4/ * Verify login page title as guru99 bank * Login to application * Verify the home page using Dashboard message */ @Test(priority=0) public void test_Home_Page_Appear_Correct(){ //Create Login Page object objLogin = new Guru99Login(driver); //Verify login page title String loginPageTitle = objLogin.getLoginTitle(); Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank")); //login to application objLogin.loginToGuru99("mgr123", "mgr!23"); // go the next page objHomePage = new Guru99HomePage(driver); //Verify home page Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123")); }
ページファクトリーとは何ですか Selenium?
ページファクトリー Selenium は、組み込みのページ オブジェクト モデル フレームワークの概念です。 Selenium WebDriver ですが、非常に最適化されています。これは、Page オブジェクトの初期化、または Page オブジェクト自体のインスタンス化に使用されます。 「FindElement/s」を使用せずに Page クラス要素を初期化するためにも使用されます。
ここでも、ページ オブジェクト リポジトリとテスト メソッドの分離の概念に従います。さらに、クラス PageFactory の助けを借りて、 Selenium、注釈を使用します @FindBy WebElement を見つけます。 initElements メソッドを使用して Web 要素を初期化します
@FindBy 受け入れることができます tagName、partialLinkText、名前、linkText、id、css、className、xpath 属性として。
Page Factory を使用して上記と同じ例を見てみましょう
Page Factory を使用した Guru99 ログイン ページ
package PageFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class Guru99Login { /** * All WebElements are identified by @FindBy annotation */ WebDriver driver; @FindBy(name="uid") WebElement user99GuruName; @FindBy(name="password") WebElement password99Guru; @FindBy(className="barone") WebElement titleText; @FindBy(name="btnLogin") WebElement login; public Guru99Login(WebDriver driver){ this.driver = driver; //This initElements method will create all WebElements PageFactory.initElements(driver, this); } //Set user name in textbox public void setUserName(String strUserName){ user99GuruName.sendKeys(strUserName); } //Set password in password textbox public void setPassword(String strPassword){ password99Guru.sendKeys(strPassword); } //Click on login button public void clickLogin(){ login.click(); } //Get the title of Login Page public String getLoginTitle(){ return titleText.getText(); } /** * This POM method will be exposed in test case to login in the application * @param strUserName * @param strPasword * @return */ public void loginToGuru99(String strUserName,String strPasword){ //Fill user name this.setUserName(strUserName); //Fill password this.setPassword(strPasword); //Click Login button this.clickLogin(); } }
Page Factory を使用した Guru99 ホームページ
package PageFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class Guru99HomePage { WebDriver driver; @FindBy(xpath="//table//tr[@class='heading3']") WebElement homePageUserName; public Guru99HomePage(WebDriver driver){ this.driver = driver; //This initElements method will create all WebElements PageFactory.initElements(driver, this); } //Get the User name from Home Page public String getHomePageDashboardUserName(){ return homePageUserName.getText(); } }
ページファクトリーのコンセプトを備えた Guru99 テストケース
package test; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import PageFactory.Guru99HomePage; import PageFactory.Guru99Login; public class Test99GuruLoginWithPageFactory { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; Guru99Login objLogin; Guru99HomePage objHomePage; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("http://demo.guru99.com/V4/"); } /** * This test go to http://demo.guru99.com/V4/ * Verify login page title as guru99 bank * Login to application * Verify the home page using Dashboard message */ @Test(priority=0) public void test_Home_Page_Appear_Correct(){ //Create Login Page object objLogin = new Guru99Login(driver); //Verify login page title String loginPageTitle = objLogin.getLoginTitle(); Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank")); //login to application objLogin.loginToGuru99("mgr123", "mgr!23"); // go the next page objHomePage = new Guru99HomePage(driver); //Verify home page Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123")); } }
完全なプロジェクト構造は次の図のようになります。
AjaxElementLocatorFactory
AjaxElementLocatorFactory PageFactory の遅延読み込みの概念です。 Selenium。これは、要素が何らかの操作で使用されている場合にのみWeb要素を見つけるために使用されます。オブジェクトページクラスにWebElementsのタイムアウトを割り当てます。パターンPageFactoryを使用する主な利点の1つは、 Selenium は AjaxElementLocatorFactory クラスです。
ここで、要素に対して操作が実行されると、その瞬間からのみその要素の可視性の待機が開始されます。指定された時間間隔内に要素が見つからない場合は、 テストケース 実行すると「NoSuchElementException」例外がスローされます。
まとめ
- ページオブジェクトモデルの Selenium WebDriver はオブジェクト リポジトリの設計パターンです。
- Selenium ページ オブジェクト モデルは、保守可能で再利用可能なテスト コードを作成します。
- Page Factory は、Page Object Model フレームワークの概念でオブジェクト リポジトリを作成するための最適化された方法です。
- AjaxElementLocatorFactory は、ページ ファクトリー (WebElement が任意の操作で使用される場合にのみ WebElement を識別するページ オブジェクト デザイン パターン) における遅延読み込みの概念です。