PO模型

PO 模型介绍
在自动化中, Selenium 自动化测试中有一个名字经常被提及 PageObject( 思想与面向对象的特征相同) ,通常 PO 模型可以大大提高测试用例的维护效率
优点 : 重用,业务和对象分离,代码结构清晰,方便代码维护
 
PageObject 设计模式
 
PO 的核心要素
1. PO 模式中抽离封装集成一个 BasePage 类,该基类应该拥有一个只实现 webdriver 实例的属性
2. 每一个 page 都继承 BasePage ,通过 driver 来管理本 page 中元素,将 page 中的操作封装成一个个方法
3.TestCase 继承 unittest.Testcase 类,并依赖 page 类,从而实现相应的测试步骤
 
PO 实现
效果展示
 
代码展示
from selenium import webdriver
from time import sleep
driver = webdriver . Firefox ()
driver . get ( "http://www.baidu.com" )
driver . find_element_by_id ( "kw" ). send_keys ( "jack" )
sleep ( 1 )
driver . find_element_by_id ( "su" ). click ()
sleep ( 2 )
driver . quit ()
 
代码分析
不同的运行脚本环境,游览器不同:驱动 webdriver.Firefox() 可以剥离
请求地址的变化 ( 生产环境和测试环境 ):url = http://www.baidu.com 可以剥离
操作元素时,常常要等待元素加载完成方可进行操作:可以把 webdriver 提供的 find_element* 方法封装,在元素操作前,先判断元素是否可以操作
实际测试场景中,可能有多个测试场景,如果每个测试场景都需要维护 url, 游览器驱动 , 元素定位等 , 效率会非常低
因此基于以上分析,是否可以设计一个所有测试界面( selenium 本身是 B/S 系统开展测试)的基类,来 维护公共的方法,此处定义名字为BasePage.py, 用于存放页面公共方法及 webdriver 原有方法二次封装等。
 
 
PO 实现
实现 BasePage
 
代码展示:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains        #鼠标操作
class BasePage():
    '''BasePage封装所有界面都公用的方法。例如driver,find_element等'''
    '''实例化BasePage类时,事先执行的__init__方法,该方法需要传递参数'''
    def __init__(self,driver,url):
        self.driver = driver
        self.base_url = url
        # 进入网址
    def get(self):
        self.driver.get(self.base_url)
        #元素定位,替代八大定位
    def get_element(self,*locator):
        return self.driver.find_element(*locator)
        #点击
    def left_click(self,*locator):
        ActionChains(self.driver).click(self.get_element(*locator)).perform()
        #输入
    def send_text(self,text,*locator):
        self.driver.find_element(*locator).send_keys(text)
        #清除
    def clear_text(self, *locator):
        self.driver.find_element(*locator).clear()
        # 表单切换
    def switch_iframe(self,*locator):
        self.driver.switch_to.frame(self.driver.find_element(*locator))
        #窗口切换
    def switch_window(self,n):
        self.driver.switch_to.window(self.driver.window_handles[n])

 

实现 SearchPage
 
代码展示:
from selenium.webdriver.common.by import By
from base_demo.BasePage import BasePage
class Search(BasePage):
    def __init__(self,driver,url):
        BasePage.__init__(self,driver,url)
        # 进入百度
    def open_baidu(self):
        self.get()
        # 输入搜索内容
    def input_search_content(self,text):
        self.send_text(text,By.ID,"kw")
        # 点击百度一下按钮,搜索
    def click_baidu_search(self):
        self.left_click(By.ID,"su")
        # 点击输入hao123
    def hao123(self):
        self.left_click(By.XPATH,'//*[@id="1"]/h3/a[1]')


实现 TestCase
代码展示:
import unittest
from selenium import webdriver
from pagedemo.search_page import Search
from pagedemo.ditu import Search2
class BaiBu(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        cls.driver = webdriver.Chrome(executable_path=r'G:\Google\Application\chromedriver.exe')
        # 10秒之内执行完,如果没执行完则报错
        cls.driver.implicitly_wait(10)
    def test001(self):
        # 网址
        url="http://www.baidu.com"
        # 第一个方法里面的传值
        s = Search(self.driver,url)
        # 调用第一个方法里面的方法
        s.open_baidu()
        s.input_search_content("123")
        s.click_baidu_search()
        s.hao123()
        # 获取句柄,并调用
        self.driver.switch_to.window(self.driver.window_handles[1])

    def test002(self):
        # 因为相当于继续往下执行,调用第一个方法里面的url,所以这个里面可以不填
        url=""
        # 第二个方法里面的传值
        s=Search2(self.driver,url)
        # 调用第二个方法里面的方法
        s.baidu()

    @classmethod
    def tearDownClass(cls) -> None:
        # cls.driver.quit()
        # 设置为pass则表示执行完停留当前页面,如果不设置为pass则执行完最后一条,直接关闭页面
        pass
if __name__ == '__main__':
    unittest.main()

第一个页面的方法的实现:

代码展示:

from selenium.webdriver.common.by import By
from base_demo.BasePage import BasePage
class Search(BasePage):
    def __init__(self,driver,url):
        BasePage.__init__(self,driver,url)
        # 进入百度
    def open_baidu(self):
        self.get()
        # 输入搜索内容
    def input_search_content(self,text):
        self.send_text(text,By.ID,"kw")
        # 点击百度一下按钮,搜索
    def click_baidu_search(self):
        self.left_click(By.ID,"su")
        # 点击输入hao123
    def hao123(self):
        self.left_click(By.XPATH,'//*[@id="1"]/h3/a[1]')


第二个页面的方法的实现:

代码展示:

from selenium.webdriver.common.by import By
from base_demo.BasePage import BasePage
class Search2(BasePage):
    def __init__(self,driver,url):
        BasePage.__init__(self,driver,url)
    def baidu(self):
        self.left_click(By.LINK_TEXT,"百度地图")

 

 

组织代码:

总结:

PO 设计模式中的 BasePage 基类对应案例中的 BasePage.py 文件
PO 模式中的 pages 中的案例显示 Search.py
PO 模式设计中 TestCase 对应案例中的 TestCase.py
 
PO 模式的优点
1:PO 提供了一种业务流程与页面元素操作分离的模式,这使得测试代码变得更加清晰
2 :页面对象与用例分离,使得我们更好的复用对象
3 :可复用的页面方法代码会变得更加优化
4 :更加有效的命令方式使得我们更加清晰的知道方法所操作的 UI 元素
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值