在selenium中使用AjaxElementLocatorFactory來優化PO模式
之前看到的一篇對於po的改進的文章,非常有啟發,簡單翻譯改寫了一下,希望對大家有幫助。本文基於java,至於其他語言是否有類似的實現,沒有具體研究過。
原文地址: http://www.eliasnogueira.com/better-page-objects-strategy-using-ajaxelementlocatorfactory-with-selenium-and-java
PO模式是page object factory設計模式的簡稱,主要是以頁面為維度來聚合一些元素的定位,讓代碼有更好的維護性和重用性,具體細節可以看這裏:https://www.selenium.dev/documentation/test_practices/encouraged/page_object_models。這裏是官方文檔,非常值得精讀。
Page Factory
如果你已經對po很熟悉了,下面的內容可以放心跳過。
下面是最基本的Page Factory套路,本質上是按頁面去封裝元素定位和操作。
public class PageObjectExample { private final WebDriver driver; public PageObjectExample(WebDriver driver) { this.driver = driver; } public void login(String email, String password) { driver.findElement(By.id("email")).sendKeys(email); driver.findElement(By.id("password")).sendKeys(password); driver.findElement(By.name("next")).click(); } }
上面的代碼只能説懂的都懂,不過這裏有個問題,在login方法裏,我們頻繁使用 driver.findElement
方法,這會顯得有一些的囉嗦,下面是改進版本,優雅了很多。
public class PageObjectExample { @FindBy(id = "email") private WebElement email; @FindBy(id = "password") private WebElement password; @FindBy(name = "next") private WebElement next; public PageObjectExample(WebDriver driver) { PageFactory.initElements(driver, this); } public void login(String email, String password) { this.email.sendKeys(email); this.password.sendKeys(password); next.click(); } }
這裏要注意的是在進行初始化的時候,需要調用 PageFactory.initElements(driver, this);
本質上這行代碼的作用是將上面的註解@FindBy轉換成基本的 findElement
形式。
參考資料:https://github.com/SeleniumHQ/selenium/wiki/PageFactory
PO模式的常見問題
等待策略。selenium提供了3種測試,分別是顯示,隱式,以及流利等待(fluent wait),一般情況下隱式等待是不推薦的。
在po中,我們會在2種情況下用到等待,分別是初始化po對象時以及在action方法時,action方式其實就是指的包含有元素操作的方法。
初始化時等待
如果操作的對象在頁面加載時候就會渲染完畢的話,那麼在初始化時等待將會是一個非常好的實踐。總體的實現思路是在初始化時告訴po,我們明確希望等待哪個元素出現,並且最多等待多久。
public class PageObjectExample { private WebDriver driver; @FindBy(id = "email") private WebElement email; @FindBy(id = "password") private WebElement password; @FindBy(name = "next") private WebElement next; public PageObjectExample(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); new WebDriverWait(driver, Duration.of(5, ChronoUnit.SECONDS)) .until(ExpectedConditions.visibilityOf(email)); } public void login(String email, String password) { this.email.sendKeys(email); this.password.sendKeys(password); next.click(); } }
上面的代碼中我們希望在初始化頁面對象時,其實也就是在頁面加載的時候明確等待email這個元素出現,超時時間為5s。
操作時等待
這裏的做法是先等待再操作,比如
public class PageObjectExample { private WebDriver driver; @FindBy(id = "email") private WebElement email; @FindBy(id = "password") private WebElement password; @FindBy(name = "next") private WebElement next; public PageObjectExample(WebDriver driver) { PageFactory.initElements(driver, this); } public void fillEmail(String email) { new WebDriverWait(driver, Duration.of(5, ChronoUnit.SECONDS)) .until(ExpectedConditions.visibilityOf(this.email)); this.email.sendKeys(email); } }
其實就是把等待的代碼換了個位置而已。
簡化等待操作
上面方式可以運行的很好,不過還是有點太囉嗦了,下面的做法可以緩解一下
•
在 PageFactory.initiElements
中調用 AjaxElementLocatorFactory 方法,這樣可以無腦等待;
•
繼承PageFactory.initiElements方法,這樣子類裏就不用反覆寫了
下面是基本的代碼
public class PageObjectExample { private WebDriver driver; // WebElements ignored public PageObjectExample(WebDriver driver) { PageFactory.initElements(new AjaxElementLocatorFactory(driver, 5), this); } }
使用繼承來簡化代碼
public abstract class AbstractPageObject { private WebDriver driver; protected AbstractPageObject(WebDriver driver) { PageFactory.initElements(new AjaxElementLocatorFactory(driver, 5), this); } } public class PageObject extends AbstractPageObject { // WebElements ignored protected PageObject(WebDriver driver) { super(driver); } // action steps ignored }
總結
大家可以通過https://github.com/eliasnogueira/selenium-java-lean-test-architecture這個項目來熟悉上面的概念,如果你使用java的話,該項目可以直接做腳手架使用,寫框架的同學可以參考。
- 測試同學找工作要不要刷題
- 在selenium中使用AjaxElementLocatorFactory來優化PO模式
- 全功能測試框架 - Carina
- 沒有QA就沒有Bug
- selenium環境管理
- 自動化用例編寫之俗手、本手、妙手
- ddddocr 驗證碼識別
- PyScript - 在HTML中寫Python
- 假如我被裁員了
- playwright 輔助工具
- 高顏值測試報告 - XTestRunner
- 基於selenium API的二次開發
- Monkey工具之fastbot-Android實踐
- 自動化測試框架設計-學會構建python包
- 深度介紹 seldom 自動化測試框架設計
- 接口測試進階:在接口測試中框架中使用json schema
- 我們為什麼用seldom做接口測試
- 自動化測試框架設計-04開發pytest插件
- Monkey工具之fastbot-iOS實踐
- 自動化測試框架設計-03單元測試框架