IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 8.Page Object -> 正文阅读

[开发测试]8.Page Object

Page Object 是 UI 自动化测试项目开发实践的最佳设计模式之一,它的主要特点体现在对界面交互细节的封装上,使测试用例更专注于业务的操作,从而提高测试用例的可维护性。

1. 认识 Page Object

当为 Web 页面编写测试时,需要操作该 Web 页面上的元素。直接操作这些元素,这样代码十分脆弱,因为 UI 会经常变动。

page 对象的一个基本经验法则是:凡是人能做的事,page 对象通过软件客户端都能做到。它提供一个易于编程的接口,并隐藏窗口中底层的部件。page 对象把在 GUI 控件上所有查询和操作数据的行为封装为方法。

一个好的经验法则是,即使改变具体的元素,page 对象的接口也不应当发生变化。

页面上有重要意义的元素可以独立为一个 page 对象。经验法则的目的是通过给页面建模,使其对应用程序的使用者变得有意义。

Page Object 是一种设计模式,在自动化测试开发中应遵循这种设计模式来编写代码。
Page Object 应该遵循以下原则进行开发:

  • Page Object 应该易于使用。
  • 有清晰的结构,如 PageObjects 对应页面对象,PageModules 对应页面内容。
  • 只写测试内容,不写基础内容。
  • 在可能的情况下防止样板代码。
  • 不需要自己管理浏览器。
  • 在运行时选择浏览器,而不是类级别。
  • 不需要直接接触 Selenium。

2. 实现 Page Object

(1)Page Object 简单实例

当有以下测试代码 test_baidu.py ,两条测试用例中重复使用了元素的定位和操作,当元素定位变化后,那么这两条测试用例都需要修改。如果测试用例有几百条,UI 频繁变化,那么自动化测试用例维护成本较高。

...

    def test_baidu_search_case1(self):
        """ 搜索关键字:selenium """
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys('selenium')
        self.driver.find_element_by_id('su').click()
        sleep(2)

    def test_baidu_search_case2(self):
        """ 搜索关键字:page object """
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys('page object')
        self.driver.find_element_by_id('su').click()
        sleep(2)

...

Page Object 的设计思想上是把元素定位与元素操作进行分层,这样带的来最直接的好处就是当元素发生变化时,只需维护 page 层的元素定位,而不需要关心在哪些测试用例当中使用了这些元素。

创建 baidu_page.py 文件,代码如下:

class BaiduPage():
    def __init__(self, driver):
        self.driver = driver

    def search_input(self, search_key):
        self.driver.find_element_by_id('kw').send_keys(search_key)

    def search_button(self):
        self.driver.find_element_by_id('su').click()

修改 test_baidu.py,修改部分如下:

from baidu_page import BaiduPage
...

    def test_baidu_search_case1(self):
        """ 搜索关键字:selenium """
        self.driver.get(self.base_url)
        bd = BaiduPage(self.driver)
        bd.search_input('selenium')
        bd.search_button()
        sleep(2)

    def test_baidu_search_case2(self):
        """ 搜索关键字:page object """
        self.driver.get(self.base_url)
        bd = BaiduPage(self.driver)
        bd.search_input('page object')
        bd.search_button()
        sleep(2)

...

导入 BaiduPage 类,每个测试用例中为 BaiduPage 类传入驱动,用封装的方法设计测试用例,就能在测试用例中消除元素定位。

(2)改进Page Object 封装

上面例子演示了 Page Object 设计模式的基本原理,也带来了点问题,例如,需要写更多的代码了。为了使 Page 层的封装更加方便,我们做一些改进。

创建 base.py 文件,代码如下:

class BasePage:
    """
    基础 Page 层,封装一些常用方法
    """
    
    def __init__(self, driver):
        self.driver = driver
        
    # 打开页面
    def open(self, url=None):
        if url is None:
            self.driver.get(self.url)
        else:
            self.driver.get(url)
    
    # id 定位
    def by_id(self, id_):
        return self.driver.find_element_by_id(id_)
    
    # name 定位
    def by_name(self, name):
        return self.driver.find_element_by_name(name)
    
    # class 定位
    def by_class(self, class_name):
        return self.driver.find_element_by_class(class_name)
    
    # XPath 定位
    def by_xpath(self, xpath):
        return self.driver.find_element_by_xpath(xpath)
    
    # CSS 定位
    def by_css(self, css):
        return self.driver.find_element_by_css_selector(css)
    
    # 获取title
    def get_title(self):
        return self.driver.title
    
    # 获取页面 text,仅使用 XPath 定位
    def get_text(self, xpath):
        return self.by_xpath(xpath).text
    
    # 执行 JavaScript 脚本
    def js(self, script):
        self.driver.execute_script(script)       

创建 BasePage 类作为所有 Page 类的基类,在 BasePage 类中封装一些自动化开发常用的方法。
open() 方法用于打开网页,url 参数默认为 None,则默认打开子类中定义的 url。(子类是后面的 BasePage 类)
get_text()方法需要接收元素定位,这里默认为 XPath 定位。

修改 baidu_page.py 文件,代码如下:

from base import BasePage


class BaiduPage(BasePage):
    """百度 Page 层, 百度页面封装操作到的元素"""
    url = "https://www.baidu.com"

    def search_input(self, search_key):
        self.by_id('kw').send_keys(search_key)

    def search_button(self):
        self.by_id('su').click()

修改 test_baidu.py 文件,代码如下:

import unittest
from time import sleep
from selenium import webdriver
from baidu_page import BaiduPage


class TestBaidu(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome()

    def test_baidu_search_case1(self):
        page = BaiduPage(self.driver)
        page.open()
        page.search_input('selenium')
        page.search_button()
        sleep(2)
        self.assertEqual(page.get_title(), "selenium_百度搜索")

    def test_baidu_search_case2(self):
        page = BaiduPage(self.driver)
        page.open()
        page.search_input('page object')
        page.search_button()
        sleep(2)
        self.assertEqual(page.get_title(), "page object_百度搜索")

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()


if __name__ == '__main__':
    unittest.main(verbosity=2)

3. poium 测试库

poium 是一个基于 Selenium/appium 的 Page Object 测试库,最大的特点是简化了 Page 层元素的定义。
支持 pip 安装,pip install poium

(1)基本使用

使用 poium 重写 baidu_page.py,修改如下:

from poium import Page, Element

class BaiduPage(Page):
    """百度 Page 层,百度页面封装操作到的元素"""
    search_input = Element(id_='kw')
    search_button = Element(id_='su')

调用 Element 类定义元素定位,并赋值给变量,这里仅封装元素的定位,并返回元素对象,元素的具体操作仍然在测试用例中完成。符合 Page Object 的思想,将元素定位与元素操作分层。

修改 test_baidu.py ,代码如下:

import unittest
from time import sleep
from selenium import webdriver
from baidu_page import BaiduPage


class TestBaidu(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome()

    def test_baidu_search_case1(self):
        page = BaiduPage(self.driver)
        page.get("https://www.baidu.com")
        page.search_input = 'selenium'
        page.search_button.click()
        sleep(2)
        self.assertEqual(page.get_title, "selenium_百度搜索")

    def test_baidu_search_case2(self):
        page = BaiduPage(self.driver)
        page.get("https://www.baidu.com")
        page.search_input = 'page object'
        page.search_button.click()
        sleep(2)
        self.assertEqual(page.get_title, "page object_百度搜索")

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()


if __name__ == '__main__':
    unittest.main(verbosity=2)

(2)更多用法

a. 支持的定位方式
poium 支持 8 种定位方式。

from poium import Page, Element

class SomePage(Page):
    elem_id = Element(id_='id')
    elem_name = Element(name='name')
    elem_class = Element(class_name='class')
    elem_tag = Element(tag='input')
    elem_link_text = Element(link_text='this_is_link')
    elem_partial_link_text = Element(partial_link_text='is_link')
    elem_xpath = Element(xpath='//*[@id="kk"]')
    elem_css = Element(css='#id')

b. 设置元素超时时间
通过 timeout 参数可设置元素超时时间,默认为 10s。

from poium import Page, Element

class SomePage(Page):
    search_input = Element(id_='kw', timeout=5)
    search_button = Element(id_='su', timeout=30)

**c.**设置元素描述
元素非常多时,必须通过注释来增加可读性,可以使用 describe 参数。

from poium import Page, Element

class SomePage(Page):
	"""
	登录 Page 类
	"""
	username = Element(css='#loginAccount', describe='用户名')
	password = Element(css='#loginPwd', describe='密码')
	login_button = Element(css='#login_btn', describe='登录按钮')
	user_info = Element(css='a.nav_user_name > span', describe='用户信息')

d. 定位一组元素
可使用 Elements 类。

from poium import Page, Elements

class SomePage(Page):
	# 定位一组元素
	search_result = Elements(xpath='//div/h3/a')

poium 极大地简化了 Page 层的定义,它还提供了很多的 API,如 PageSelect类简化了下拉框的处理等。目前,poium 已经在Web 自动化项目中得到了很好的应用。

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-22 14:29:45  更:2021-07-22 14:31:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 18:50:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码