不懂PO 设计模式?这篇实战文带你解决 PO


为UI页面写测试用例时(比如web页面,移动端页面),测试用例会存在大量元素和操作细节。当UI变化时,测试用例也要跟着变化, PageObject 很好的解决了这个问题!

使用UI自动化测试工具时(包括selenium,appium等),如果无统一模式进行规范,随着用例的增多会变得难以维护,而 PageObject 让自动化脚本井井有序,将 page 单独维护并封装细节,可以使 testcase 更稳健,不需要大改大动。

具体做法:把元素信息和操作细节封装到Page类中,在测试用例上调用Page对象(PageObject),比如存在一个功能“选取相册标题”,需要为之建立函数selectAblumWithTitle(),函数内部是操作细节findElementsWithClass(‘album’)等:


以选“取相册标题”举例,伪代码如下:

selectAblumWithTitle() {
    #选取相册
    findElementsWithClass('album')
    #选取相册标题
    findElementsWithClass('title-field')
    #返回标题内容
    return getText()

}

page object的主要原则是提供一个简单接口 (或者函数,比如上述的selectAblumWithTitle),让调用者在页面上可以做任何操作,点击页面元素,在输入框输入内容等。

因此,如果要访问一个文本字段,page object应该有获取和返回字符串的方法。page object应该封装对数据的操作细节,比如查找元素和点击元素。当页面元素改动时,应该只改变page类中的内容,不需要改变调用它的地方。

不要为每个UI页面都创建一个page类,应该只为页面中重要的元素创建page类。

比如,一个页面显示多个相册,应该创建一个相册列表page object,它包含许多相册page object。如果某些复杂UI的层次结构只是用来组织UI,那么它就不应该出现在page object中。page object的目的是通过给页面建模,从而对应用程序的使用者变得有意义:

如果你想导航到另一个页面,初始page对象应当return另一个page对象,比如点击注册,进入注册页面,在代码中就应该return Register()。如果想获取页面信息,可以return基本类型(字符串、日期)。

建议不要在page object中放断言。应该去测page object,而不是让page object自己测自己,page object的责任是提供页面的状态信息。这里仅用HTML描述Page Object,这种模式还可以用来隐藏Java swing UI细节,它可用于所有UI框架。

PageObject的核心思想是六大原则,掌握六大原则才可以进行 PageObject 实战演练,这是 PageObject的精髓所在。
selenium官方凝聚出六大原则,后面的PageObject使用都将围绕六大原则开展:

  • 公共方法代表页面提供的服务
  • 不要暴露页面细节
  • 不要把断言和操作细节混用
  • 方法可以return到新打开的页面
  • 不要把整页内容都放到PO中
  • 相同的行为会产生不同的结果,可以封装不同结果

下面,对上述六大原则进行解释:

  • 原则一:要封装页面中的功能(或者服务),比如点击页面中的元素,可以进入到新的页面,于是,可以为这个服务封装方法“进入新页面”。
  • 原则二:封装细节,对外只提供方法名(或者接口)。
  • 原则三:封装的操作细节中不要使用断言,把断言放到单独的模块中,比如testcase。
  • 原则四:点击一个按钮会开启新的页面,可以用return方法表示跳转,比如return MainPage()表示跳转到新的PO:MainPage。
  • 原则五:只为页面中重要的元素进行PO设计,舍弃不重要的内容。
  • 原则六:一个动作可能产生不同结果,比如点击按钮后,可能点击成功,也可能点击失败,为两种结果封装两个方法,click_success和click_error。

以企业微信首页为例,企业微信首页有二个主要功能:立即注册和企业登录。
企业微信网址:https://work.weixin.qq.com/


点击企业登录可以进入登录页面,在页面可以扫码登录和企业注册。


点击企业注册可以进入注册页面,在页面可以输入相关信息进行注册。

用page object原则为页面建模,这里涉及三个页面:首页,登录,注册。在代码中创建对应的三个类Index,Login,Register:
• 登陆页⾯提供login findPassword功能
– Login类 + login findPassword⽅法
• 登录页⾯内的元素有多少并不关⼼,隐藏内部界⾯控件
• 登录成功和失败会分别返回不同的页⾯
– findPassword
– loginSuccess
– loginFail
• 通过⽅法返回值判断登录是否符合预期

BasePage是所有page object的父类,它为子类提供公共的方法,比如下面的BasePage提供初始化driver和退出driver,代码中在base_page模块的BasePage类中使用__init__初始方法进行初始化操作,包括driver的复用,driver的赋值,全局等待的设置(隐式等待)等等:

from time import sleep
from selenium import webdriver
from selenium.webdriver.remote.webdriver import WebDriver


class BasePage:
    def __init__(self, driver: WebDriver = None):
        #此处对driver进行复用,如果不存在driver,就构造一个新的
        if driver is None:
            # Index页面需要用,首次使用时构造新driver
            self._driver = webdriver.Chrome()
            # 设置隐式等待时间
            self._driver.implicitly_wait(3)
            # 访问网页
            self._driver.get(self._base_url)
        else:
            # Login与Register等页面需要用这个方法,避免重复构造driver
            self._driver = driver

    def close(self):
        sleep(20)
        self._driver.quit()


Index是企业微信首页的page object,它存在两个方法,进入注册page object和进入登录page object,这里return方法返回page object实现了页面跳转,比如:goto_register方法return Register,实现从首页跳转到注册页:

class Index(BasePage):
    _base_url = "https://work.weixin.qq.com/"
    # 进入注册页面
    def goto_register(self):
        self._driver.find_element(By.LINK_TEXT, "立即注册").click()
        # 创建Register实例后,可调用Register中的方法
        return Register(self._driver)
    # 进入登录页面
    def goto_login(self):
        self._driver.find_element(By.LINK_TEXT, "企业登录").click()
        # 创建Login实例后,可调用Login中的方法
        return Login(self._driver)


Login是登录页面的page object,主要功能有:进入注册页面,扫描二维码,因此创建两个方法代表两个功能:scan_qrcode和goto_registry。代码跟上面相似,不过多介绍:

from selenium.webdriver.common.by import By
from test_selenium.page.base_page import BasePage
from test_selenium.page.register import Register

class Login(BasePage):
    # 扫描二维码
    def scan_qrcode(self):
        pass
    # 进入注册页面
    def goto_registry(self):
        self._driver.find_element(By.LINK_TEXT, "企业注册").click()
        return Register(self._driver)


Register是注册页面的page object,主要功能是填写正确注册信息,当填写错误时,返回错误信息。register方法实现了正确的表格填写,当填写完毕时返回自身(页面还停留在注册页)。get_error_message方法实现了错误填写的情况,如果填写错误,就收集错误内容并返回:

from selenium.webdriver.common.by import By
from test_selenium.page.base_page import BasePage


class Register(BasePage):
    # 填写注册信息,此处只填写了部分信息,并没有填写完全
    def register(self, corpname):
        # 进行表格填写
        self._driver.find_element(By.ID, "corp_name").send_keys(corpname)
        self._driver.find_element(By.ID, "submit_btn").click()
        # 填写完毕,停留在注册页,可继续调用Register内的方法 
        return self
    #填写错误时,返回错误信息
    def get_error_message(self):
        # 收集错误信息并返回
        result=[]
        for element in self._driver.find_elements(By.CSS_SELECTOR, ".js_error_msg"):
            result.append(element.text)

        return result


test_index模块是对上述功能的测试,它独立于page类,在TestIndex类中只需要调用page类提供的方法即可,比如下面对注册页及登陆页的测试使用了test_register和test_login方法:

from test_selenium.page.index import Index


class TestIndex:
    # 所有步骤前的初始化
    def setup(self):
        self.index = Index()
    # 对注册功能的测试
    def test_register(self):
        # 进入index,然后进入注册页填写信息
        self.index.goto_register().register("霍格沃兹测试学院")
    # 对login功能的测试
    def test_login(self):
        # 从首页进入到注册页
        register_page = self.index.goto_login().goto_registry()\
            .register("测吧(北京)科技有限公司")
        # 对填写结果进行断言,是否填写成功或者填写失败
        assert "请选择" in "|".join(register_page.get_error_message())
    # 关闭driver
    def teardown(self):
        self.index.close()

获取更多相关资料:请添加vx,ceshiren001
https://qrcode.ceba.ceshiren.com/link?name=article&project_id=qrcode&from=CSDN&timestamp=1653382018&author=MM

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程介绍你是否在寻找机会进入自动化测试领域? 你是否渴望学习selenium webdriver + Java以及最新的框架和技术进行web自动化测试? 你是否感兴趣学习Selenium如何用在你现有的项目里的? 这门课带你从Selenium搭建环境开始讲起,然后学习selenium,TestNG, logback, maven, jenkins。 我们假设学员没有任何自动化经验,来设计的这套课程。每个课题都从最基础的开始讲起。Selenium相关的该覆盖的课题都覆盖了。 例子都是来自于真实的web应用项目,帮助你理解不同的组件怎么用上自动化,这将展示给你一个行业层面的框架,增加自信心。 全网没有其他课程像这门课涵盖到如此之深的细节。 您将会学到什么 学完课程以后,你将拥有完整的Selenium Webdriver知识 你将具备从头开始设计Page Object、Page Factory、DATADRIVEN等搭建自动化框架的能力 用100多个实例对Selenium现实场景应用进行深入理解 全面了解TestNG, Maven, Jenkins, HTML报告,多浏览器并行测试 了解数据库测试和使用Selenium进行性能测试 你将彻底了解testNG框架 你从网上随便选择一个网站,都可以实现自动化,用所有可能的测试用例进行自动化测试 将提高你的编码技能,以编写最优化的自动化测试用例代码 你基本可以搞定任何Selenium面试,并能从设计阶段开始领导整个Selenium自动化项目 你应该能够使用应用程序的GUI来验证数据完整性 你将能够创建漂亮的报告来打动客户或领导 更深入地理解自动化指南和代码质量标准 会附带一个练习网站,可以用上所有可用的WebDriver功能,实现自动化 【适合人群】 软件手动测试人员想转为自动化测试的人员 自动化软件测试人员想加强专业技能的 刚毕业学生想从事软件行业 QA 组长或项目经理 【课程优势】 学完课程以后,你将拥有完整的Selenium Webdriver知识 【讲师介绍】 资质介绍: 12年以上软件测试工作经验,其中7年以上自动化测试开发经验 新书“Python3+Selenium3自动化测试项目实战”作者

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值