UI 自动化测试中的链式调用设计
目录
UI 自动化测试中的链式调用设计
一、问题
传统的 UI 自动化测试代码往往是这样写的:
def test_login_and_create_report():
driver.get("/login")
driver.find_element(By.ID, "username").send_keys("admin")
driver.find_element(By.ID, "password").send_keys("admin123")
driver.find_element(By.ID, "login-btn").click()
driver.get("/reports")
driver.find_element(By.ID, "new-report").click()
driver.find_element(By.ID, "report-name").send_keys("测试报表")
driver.find_element(By.ID, "save-btn").click()
assert "创建成功" in driver.page_source问题很明显:测试逻辑被一大堆底层操作淹没了,看不出主线流程。
二、链式调用
结合 POM 模式,让每个操作方法返回页面对象本身或下一个页面对象:
class LoginPage:
def enter_username(self, username):
self.driver.find_element(By.ID, "username").send_keys(username)
return self
def enter_password(self, password):
self.driver.find_element(By.ID, "password").send_keys(password)
return self
def click_login(self):
self.driver.find_element(By.ID, "login-btn").click()
return HomePage(self.driver) # 返回新页面对象
class HomePage:
def goto_reports(self):
self.driver.find_element(By.LINK_TEXT, "报表").click()
return ReportsPage(self.driver)
class ReportsPage:
def click_new_report(self):
self.driver.find_element(By.ID, "new-report").click()
return ReportFormPage(self.driver)
class ReportFormPage:
def set_name(self, name):
self.driver.find_element(By.ID, "report-name").send_keys(name)
return self
def save(self):
self.driver.find_element(By.ID, "save-btn").click()
return ReportsPage(self.driver)测试代码变成这样:
def test_login_and_create_report():
reports_page = (LoginPage(driver)
.enter_username("admin")
.enter_password("admin123")
.click_login()
.goto_reports()
.click_new_report()
.set_name("测试报表")
.save())
assert reports_page.has_success_message()三、优势
- 语义清晰:测试代码读起来像业务文档
- 减少中间变量:不需要为每个页面对象单独定义变量,代码更简洁。
- 维护成本低:页面元素变化时,只需改 Page Object 内部,测试流程代码不用动。