Selenium | PageObject原则

本文节选自霍格沃兹测试学院内部教材
PageObject 的核心思想是六大原则,掌握六大原则才可以进行 PageObject 实战演练,这是 PageObject 的精髓所在。

Selenium 官方凝聚出六大原则,后面的 PageObject 使用都将围绕六大原则开展:

  1. 公共方法代表页面提供的服务
  2. 不要暴露页面细节
  3. 不要把断言和操作细节混用
  4. 方法可以 return 到新打开的页面
  5. 不要把整页内容都放到 PO 中
  6. 相同的行为会产生不同的结果,可以封装不同结果
    下面,对上述六大原则进行解释:
  • 原则一:要封装页面中的功能(或者服务),比如点击页面中的元素,进入到新的页面,就可以为这个服务封装方法“进入新页面”。
  • 原则二:封装细节,对外只提供方法名(或者接口)。
  • 原则三:封装的操作细节中不要使用断言,把断言放到单独的模块中,比如 testcase。
  • 原则四:点击一个按钮会开启新的页面,可以用 return 方法表示跳转,比如return MainPage()表示跳转到新的 PO:即 MainPage。
  • 原则五:只为页面中重要的元素进行 PO 设计,舍弃不重要的内容。
  • 原则六:一个动作可能产生不同结果,比如点击按钮后,可能点击成功,也可能点击失败,为两种结果封装两个方法,click_successclick_error

案例

以企业微信首页为例,企业微信首页有二个主要功能:立即注册和企业登录。

企业微信网址:https://work.weixin.qq.com/

Index 页面

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

Login 页面

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

Register 页面

用 PageObject 原则为页面建模,这里涉及三个页面:首页,登录,注册。在代码中创建对应的三个类 Index、Login、Register:

  • 登陆页⾯提供 login findPassword 功能
    • Login 类 + login findPassword ⽅法
  • 登录页⾯内的元素有多少并不关⼼,隐藏内部界⾯控件
  • 登录成功和失败会分别返回不同的页⾯
    • findPassword
    • loginSuccess
    • loginFail
  • 通过⽅法返回值判断登录是否符合预期

UML图

代码

目录结构


        test_selenium │ ├─page │      base_page.py │      index.py │      login.py │      register.py │      __init__.py │ └─testcase         test_index.py         __init__.py

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


        from time import sleepfrom selenium import webdriverfrom 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 是企业微信首页的 PageObject,它存在两个方法,进入注册 PageObject 和进入登陆 PageObject,这里 return
方法返回 PageObject 实现了页面跳转。比如:goto_register 方法 return Register,实现从首页跳转到注册页。  

        from selenium.webdriver.common.by import By  
            from test_selenium.page.base_page import BasePagefrom test_selenium.page.login import Loginfrom test_selenium.page.register import 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 是登录页面的 PageObject,主要功能有:进入注册页面,扫描二维码,因此创建两个方法代表两个功能:scan_qrcode 和
goto_registry。代码跟上面相似,不过多介绍。


        from selenium.webdriver.common.by import Byfrom test_selenium.page.base_page import BasePagefrom 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 是注册页面的 PageObject,主要功能是填写正确注册信息,当填写错误时,返回错误信息。register
方法实现了正确的表格填写,当填写完毕时返回自身(页面还停留在注册页)。get_error_message
方法实现了错误填写的情况,如果填写错误,就收集错误内容并返回。


        from selenium.webdriver.common.by import Byfrom 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()  

Web自动化中PageObject 原则就先讲到这里啦,大家还想看什么内容的文章也可以留言告诉我们哦!

** _
来霍格沃兹测试开发学社,学习更多软件测试与测试开发的进阶技术,知识点涵盖web自动化测试 app自动化测试、接口自动化测试、测试框架、性能测试、安全测试、持续集成/持续交付/DevOps,测试左移、测试右移、精准测试、测试平台开发、测试管理等内容,课程技术涵盖bash、pytest、junit、selenium、appium、postman、requests、httprunner、jmeter、jenkins、docker、k8s、elk、sonarqube、jacoco、jvm-sandbox等相关技术,全面提升测试开发工程师的技术实力
QQ交流群:484590337
公众号 TestingStudio
视频资料领取:https://qrcode.testing-studio.com/f?from=CSDN&url=https://ceshiren.com/t/topic/15844
点击查看更多信息

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值