目录
- page object 模式简介
- page object 设计原则
page object 模式简介
传统 UI 自动化的问题
- 无法适应 UI 频繁变化
- 无法清晰表达业务用例场景
- 大量的样板代码 driver/find/click
POM 模式的优势
- 降低 UI 变化导致的测试用例脆弱性问题
- 让用例清晰明朗,与具体实现无关
POM 建模原则
- 字段意义
- 不要暴露页面内部的元素给外部
- 不需要建模 UI 内的所有元素
- 方法意义
- 用公共方法代表 UI 所提供的功能
- 方法应该返回其他的 PageObject 或者返回用于断言的数据
- 同样的行为不同的结果可以建模为不同的方法
- 不要在方法内加断言
POM 使用方法
- 把元素信息和操作细节封装到 PageObject 类中
- 根据业务逻辑,在测试用例中链式调用
示例展示
搜索场景:传统线性脚本(Python)
# test_search.py
from selenium import webdriver
from selenium.webdriver.common.by import By
class TestSearch:
def test_search(self):
# 初始化浏览器
self.driver = webdriver.Chrome()
self.driver.get("https://xueqiu.com/")
self.driver.implicitly_wait(3)
# 输入搜索关键词
self.driver.find_element(By.NAME, "q").send_keys("阿里巴巴-SW")
# 点击搜索按钮
self.driver.find_element(By.CSS_SELECTOR, "i.search").click()
# 获取搜索结果
name = self.driver.find_element(By.XPATH, "//table//strong").text
# 断言
assert name == "阿里巴巴-SW"
搜索场景:POM 脚本(Python)
# search_page.py
from selenium import webdriver
from selenium.webdriver.common.by import By
class SearchPage:
__INPUT_SEARCH = (By.NAME, "q")
__BUTTON_SEARCH = (By.CSS_SELECTOR, "i.search")
__SPAN_STOCK = (By.XPATH, "//table//strong")
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(3)
self.driver.get("https://xueqiu.com/")
def search_stock(self, stock_name: str):
self.driver.find_element(*self.__INPUT_SEARCH).send_keys(stock_name)
self.driver.find_element(*self.__BUTTON_SEARCH).click()
name = self.driver.find_element(By.XPATH, "//table//strong").text
return name
搜索场景:测试用例(Python)
# test_search.py
from onSelenium.fei.page_objects.search_page import SearchPage
class TestSearch:
def test_search(self):
text = SearchPage().search_stock("阿里巴巴-SW")
# 断言
assert "阿里巴巴-SW" == text
传统脚本(Java)
/***
* 示例代码 不要直接复制执行
* Tests login feature
*/
public class Login {
public void testLogin() {
// 在登录页面上填写登录数据
driver.findElement(By.name("user_name")).sendKeys("userName");
driver.findElement(By.name("password")).sendKeys("my supersecret password");
driver.findElement(By.name("sign-in")).click();
// 登录后验证h1标签是否为Hello userName
driver.findElement(By.tagName("h1")).isDisplayed();
assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
}
}
}
PageObjcet(Java)
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
/**
* Page Object encapsulates the Home Page
* 示例代码 不要直接复制执行
*/
public class HomePage {
protected WebDriver driver;
// <h1>Hello userName</h1>
private By messageBy = By.tagName("h1");
public HomePage(WebDriver driver){
this.driver = driver;
if (!driver.getTitle().equals(
"Home Page of logged in user"))
{
throw new IllegalStateException(
"This is not Home Page of logged in user," +
" current page is: " + driver.getCurrentUrl());
}
}
/**
* Get message (h1 tag)
*
* @return String message text
*/
public String getMessageText() {
return driver.findElement(messageBy).getText();
}
public HomePage manageProfile() {
// Page encapsulation to manage profile functionality
return new HomePage(driver);
}
/* 提供登录用户主页所代表的服务的更多方法.
这些方法可能会返回更多页面对象.
例如, 单击"撰写邮件"按钮可以返回ComposeMail类对象 */
}
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
/**
* 示例代码 不要直接复制执行
* Page Object encapsulates the Sign-in page.
*/
public class SignInPage {
protected WebDriver driver;
// <input name="user_name" type="text" value="">
private By usernameBy = By.name("user_name");
// <input name="password" type="password" value="">
private By passwordBy = By.name("password");
// <input name="sign_in" type="submit" value="SignIn">
private By signinBy = By.name("sign_in");
public SignInPage(WebDriver driver){
this.driver = driver;
}
/**
* Login as valid user
*
* @param userName
* @param password
* @return HomePage object
*/
public HomePage loginValidUser(
String userName, String password) {
driver.findElement(usernameBy).sendKeys(userName);
driver.findElement(passwordBy).sendKeys(password);
driver.findElement(signinBy).click();
return new HomePage(driver);
}
}
PageObject 版本测试用例(Java)
/***
* 示例代码 不要直接复制执行
*/
public class TestLogin {
@Test
public void testLogin() {
SignInPage signInPage = new SignInPage(driver);
HomePage homePage = signInPage.loginValidUser("userName", "password");
assertThat(homePage.getMessageText(), is("Hello userName"));
}
}