zoukankan      html  css  js  c++  java
  • 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
    点击获取更多信息

  • 相关阅读:
    旧梦重温
    树莓派改用中山大学软件源
    [翻译]lpeg入门教程
    为python-sproto添加map支持
    玩家回档原因分析
    为sproto添加python绑定
    如何快速编写Vim语法高亮文件
    windows调试器尝鲜
    休斯顿,我们遇到了一个问题
    糟糕的十一月
  • 原文地址:https://www.cnblogs.com/hogwarts/p/15766585.html
Copyright © 2011-2022 走看看