目录
简介
什么是PO模式
Page Object Model,是一种设计模式,提供了一种页面元素定位和业务操作流程分离的模式。当页面元素发生变化时,只需要维护对应的page层修改定位,不需要修改业务逻辑代码。
从字面意思来看,页面对象模型,即将每个页面当成一个对象,给页面写一个类。主要就是完成元素定位和业务操作,只对外提供必要的操作接口,是一种封装思想。当然不一定就是一个页面一个类,有重要意义的元素可以独立为一个page对象。
为什么使用PO设计模式
少数的自动化测试用例维护起来看起来是很容易的。但随着时间的迁移,测试套件将持续的增长。脚本也将变得越来越臃肿庞大。
如果变成我们需要维护10个页面,100个页面,甚至1000个呢?而且页面元素很多是公用的。那页面元素的任何改变都会让我们的脚本维护变得繁琐复杂,而且变得耗时易出错。
如何设计POM
PO核心思想是分层,实现脚本重复使用,易维护,可读性高。
主要分三层:
- 基础层BasePage:封装一些最基础的selenium的原生的api方法,元素定位,框架跳转等
- PO层:元素定位、获得元素对象,操作元素
- 测试用例层:业务逻辑,数据驱动
再次细分可划分为:
- base层: 最基本的页面元素定位方法的再次封装,如将find_element_by_id再次封装为一个by_id()方法,只是为了使用更加简便
- page层: 定位具体的元素,如find_email_element
- handle层:操作层,封装对具体元素的操作,如send_email
- business层:业务层,封装业务流程,如login
- case层:用例层,放不同的测试用例,如login_email_error,login_success
PO模型是种思想,不同的人会有不同的实现方式,具体可根据实际需要来划分。
实现示例
以百度搜索为例,假设有以下测试代码。
from selenium import webdriver
class Test():
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.get("http://www.baidu.com")
def test_case1(self):
self.driver.find_element_by_id("kw").clear()
self.driver.find_element_by_id("kw").send_keys("selenium")
self.driver.find_element_by_id("su").click()
def test_case2(self):
self.driver.find_element_by_id("kw").clear()
self.driver.find_element_by_id("kw").send_keys("python")
self.driver.find_element_by_id("su").click()
def end_test(self):
self.driver.quit()
if __name__ == '__main__':
test=Test()
test.test_case1()
test.test_case2()
test.end_test()
基于PO模式对代码进行封装
代码目录组织示例:
search_base.py文件。
class SearchBase(object):
def __init__(self,driver):
self.driver=driver
def by_id(self,id):
try:
return self.driver.find_element_by_id(id)
except:
return None
创建SearchBase类作为基类,封装找元素的方法,为了后面使用更加简便。
search_page.py文件。
from base.search_base import SearchBase
class SearchPage(object):
def __init__(self, driver):
self.lb = SearchBase(driver)
def input_search_keyword(self, text):
input_box = self.lb.by_id('kw')
input_box.clear()
input_box.send_keys(text)
def click_search_button(self):
self.lb.by_id('su').click()
创建SearchPage类,所有元素的定位都在这个类中,如果某个元素发生变化,只需要维护这个类中元素定位,而不需要关心在哪个测试用例中使用了这个元素。
search_case.py文件
from page.search_page import SearchPage
from selenium import webdriver
class SearchCase(object):
def __init__(self):
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.maximize_window()
self.lb = SearchPage(driver)
def test_case1(self):
self.lb.input_search_keyword('selenium')
self.lb.click_search_button()
def test_case2(self):
self.lb.input_search_keyword('python')
self.lb.click_search_button()
if __name__ == '__main__':
lc = SearchCase()
lc.test_case1()
lc.test_case2()
创建SearchCase类,在这个类中使用Page层封装的方法来设计具体的测试用例,重点关注业务流程即可。