软件测试学习笔记丨SeleniumPO模式

本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/22525
本文为霍格沃兹测试开发学社的学习经历分享,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~
说明:本篇博客基于selenium 4.1.0

什么是PO模式

PO模式的全称page object model(POM),有时候也叫做page object pattern。由马丁福勒提出,受到了selenium自动化测试框架的大力推广,因而成为一种非常主流的自动化测试设计模式
PO模式是在UI自动化测试过程当中使用非常频繁的一种设计模式,使用这种模式,可以有效的提升代码的复用能力,并且让自动化测试代码维护起来更加方便

PO模式设计

在PO模式中,使用类来表示每个UI页面,类中的属性表示页面的信息,类中的方法表示页面的行为和操作

在将页面抽象化为类时,需要注意PO模式的设计原则

  • 对于属性

    • 不要暴露页面内部的元素给外部
    • 不需要建模 UI 内的所有元素
  • 对于方法

    • 对于方法:用公共方法代表 UI 所提供的功能
    • 方法应该返回其他的 PageObject 或者返回用于断言的数据
    • 同样的行为不同的结果可以建模为不同的方法
    • 不要在方法内加断言

在这里插入图片描述

PO模式优点

  • 便于维护:每个页面对应一个类文件,前端页面被修改后只需要维护对应的类文件,不会影响其他代码,符合单一职责原则
  • 便于阅读:页面的操作都被以函数的形式封装起来了。函数名就具备注释的作用,其他人阅读代码时可以通过函数了解业务
  • 便于使用:编写用例时只需要关注测试步骤和测试结果。用例与用例间的相同操作,不用重复编写

代码示例

import yaml
import os
from selenium import webdriver
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait


class PageBase:
    """
    页面基类:处理页面公共业务、存放公共方法
    """
    def __init__(self, driver: WebDriver):
        self.driver = driver


class PageLogin(PageBase):
    """
    登录页面
    """
    # 页面url地址
    _page_url = "https://work.weixin.qq.com/wework_admin/loginpage_wx"

    def goto_index(self):
        """
        跳转到首页
        :return:
        """
        self.driver.get(self._page_url)

        if not os.path.exists("resource"):
            os.mkdir("resource")

        if os.path.exists("resource/cookie.yaml"):
            cookie = yaml.safe_load(open("resource/cookie.yaml"))
            for i in cookie:
                self.driver.add_cookie(i)
            self.driver.get("https://work.weixin.qq.com/wework_admin/frame#index")
        else:
            # 扫码登录,等待页面加载
            WebDriverWait(self.driver, 60).until(expected_conditions.url_contains("wework_admin/frame"))

            # 存入cookie
            cookie = self.driver.get_cookies()
            with open("resource/cookie.yaml", "w") as f:
                yaml.safe_dump(cookie, f)

        # 返回首页实例对象
        return PageIndex(self.driver)


class PageIndex(PageBase):
    """
    首页
    """
    # 页面url地址
    _page_url = "https://work.weixin.qq.com/wework_admin/frame#index"

    # 页面元素定位
    _path_contact = (By.ID, "menu_contacts")
    _path_addmember = (By.CSS_SELECTOR, '.ww_indexImg_AddMember')

    def goto_addmember(self):
        """
        跳转添加成员页面
        :return:
        """
        self.driver.find_element(*self._path_addmember).click()

        # 返回添加成员页面的实例对象
        return PageAddmember(self.driver)


class PageAddmember(PageBase):
    """
    添加成员页面
    """
    # 页面url地址
    _page_url = "https://work.weixin.qq.com/wework_admin/frame#contacts"

    # 页面元素定位
    _path_name = (By.ID, "username")
    _path_id = (By.ID, "memberAdd_acctid")
    _path_tel = (By.ID, "memberAdd_phone")
    _path_finish = (By.CSS_SELECTOR, ".js_btn_save")
    _path_tips = (By.CSS_SELECTOR, ".ww_inputWithTips_WithErr")

    def add_member_success(self, member_name, member_id, member_tel):
        """
        添加成员成功,跳转回通讯录页面
        :param member_name: 姓名
        :param member_id: 账号
        :param member_tel: 手机
        :return: 通讯录页面页面
        """
        self.driver.find_element(*self._path_name).send_keys(member_name)
        self.driver.find_element(*self._path_id).send_keys(member_id)
        self.driver.find_element(*self._path_tel).send_keys(member_tel)
        self.driver.find_element(*self._path_finish).click()

        # 返回页面通讯录页面实例对象
        return PageContact(self.driver)


class PageContact(PageBase):
    """
    通讯录页面
    """
    pass


# 测试用例
class TestCookie:
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(3)

    def teardown(self):
        self.driver.quit()

    # 一个简单的添加成员用例
    def test_addmember_success(self):
        data = ('llbai', '9527', '13122223333')

        # 基于已有的页面类和方法,可以快速实现登录-进入页面-进入添加成员页面-添加成员
        PageLogin(self.driver).goto_index().goto_addmember().add_member_success(*data)

在这里插入图片描述

推荐学习

【霍格沃兹测试开发】7天软件测试快速入门带你从零基础/转行/小白/就业/测试用例设计实战

【霍格沃兹测试开发】最新版!Web 自动化测试从入门到精通/ 电子商务产品实战/Selenium (上集)

【霍格沃兹测试开发】最新版!Web 自动化测试从入门到精通/ 电子商务产品实战/Selenium (下集)

【霍格沃兹测试开发】明星讲师精心打造最新Python 教程软件测试开发从业者必学(上集)

【霍格沃兹测试开发】明星讲师精心打造最新Python 教程软件测试开发从业者必学(下集)

【霍格沃兹测试开发】精品课合集/ 自动化测试/ 性能测试/ 精准测试/ 测试左移/ 测试右移/ 人工智能测试

【霍格沃兹测试开发】腾讯/ 百度/ 阿里/ 字节测试专家技术沙龙分享合集/ 精准化测试/ 流量回放/Diff

【霍格沃兹测试开发】Pytest 用例结构/ 编写规范 / 免费分享

【霍格沃兹测试开发】JMeter 实时性能监控平台/ 数据分析展示系统Grafana/Docker 安装

【霍格沃兹测试开发】接口自动化测试的场景有哪些?为什么要做接口自动化测试?如何一键生成测试报告?

【霍格沃兹测试开发】面试技巧指导/ 测试开发能力评级/1V1 模拟面试实战/ 冲刺年薪百万!

【霍格沃兹测试开发】腾讯软件测试能力评级标准/ 要评级表格的联系我

【霍格沃兹测试开发】Pytest 与Allure2 一键生成测试报告/ 测试用例断言/ 数据驱动/ 参数化

【霍格沃兹测试开发】App 功能测试实战快速入门/adb 常用命令/adb 压力测试

【霍格沃兹测试开发】阿里/ 百度/ 腾讯/ 滴滴/ 字节/ 一线大厂面试真题讲解,卷完拿高薪Offer !

【霍格沃兹测试开发】App自动化测试零基础快速入门/Appium/自动化用例录制/参数配置

【霍格沃兹测试开发】如何用Postman 做接口测试,从入门到实战/ 接口抓包(最新最全教程)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/909078.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络自动化03:简单解释send_config_set方法并举例

目录 拓扑图设备信息 netmiko涉及方法send_config_set()方法的简单示例代码输出结果代码解释导入模块配置信息config_device_interface_description 函数主程序块总结 send_config_set方法参数:1. enter_config_mode2. config_commands3. enter_config_mode4. error…

UI自动化测试 —— CSS元素定位实践!

前言 自动化测试元素定位是指在自动化测试过程中,通过特定的方法或策略来准确识别和定位页面上的元素,以便对这些元素进行进一步的操作或断言。这些元素可以是文本框、按钮、链接、图片等HTML页面上的任何可见或不可见的组件。 在自动化测试中&#xf…

zxing生成、解析二维码,条形码

1、maven依赖 <!--zxing依赖--><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.1.0</version></dependency><dependency><groupId>com.google.zxing</groupI…

有效增加网站流量的实用策略和技巧

内容概要 在数字化时代&#xff0c;网站流量的增加被视为在线业务成功的关键。网站流量不仅仅意味着访问者的数量&#xff0c;还影响着品牌知名度、用户参与度和销售转化率。针对这一需求&#xff0c;企业需要采取行之有效的策略&#xff0c;例如搜索引擎优化&#xff08;SEO&…

玄机-应急响应- Linux入侵排查

一、web目录存在木马&#xff0c;请找到木马的密码提交 到web目录进行搜索 find ./ type f -name "*.php" | xargs grep "eval(" 发现有三个可疑文件 1.php看到密码 1 flag{1} 二、服务器疑似存在不死马&#xff0c;请找到不死马的密码提交 被md5加密的…

从 vue 源码看问题 — vue 如何进行异步更新?

前言 在上一篇 如何理解 vue 响应式&#xff1f; 中&#xff0c;了解到响应式其实是通过 Observer 类中调用 defineReactive() 即 Object.defineProperty() 方法为每个目标对象的 key&#xff08;key 对应的 value 为非数组的&#xff09; 设置 getter 和 setter 实现拦截&…

本地部署bert-base-chinese模型交互式问答,gradio

首先下载bert-base-chinese&#xff0c;可以在 Huggingface, modelscope, github下载 pip install gradio torch transformers import gradio as gr import torch from transformers import BertTokenizer, BertForQuestionAnswering# 加载bert-base-chinese模型和分词器 mod…

SYN590RH是SYNOXO全新开发设计的一款宽电压范围,低功耗,高性能,无需外置AGC电容de单芯片ASK或00 K射频接收器

一般描述 SYN590RH是SYNOXO全新开发设计的一款宽电压范围&#xff0c;低功耗&#xff0c;高性能&#xff0c;无需外置AGC电容&#xff0c;灵敏度达到典型-110 dBm,400MHz~450MHz频率范围应用的单芯片ASK或00 K射频接收器。 SYN590RH是一款典型的即插即用型单片高…

Unreal5从入门到精通之如何在指定的显示器上运行UE程序

前言 我们有一个设备,是一个带双显示器的机柜,主显示器是一个小竖屏,可以触屏操作,大显示器是一个普通的横屏显示器。我们用这个机柜的原因就是可以摆脱鼠标和键盘,直接使用触屏操作,又可以在大屏观看,非常适合用于教学。 然后我们为这款机柜做了很多个VR项目,包括Uni…

C++中unordered_map和unordered_set的介绍以及用哈希表封装实现unordered_map和unordered_set

目录 1.unordered_map和unordered_set的使用 1.1unordered_set类的介绍 1.2unordered_set和set的使用差异 1.3unordered_map和map的使用差异 1.4unordered_multimap/unordered_multiset 2.用哈希表封装实现unordered_set和unordered_map 2.1实现出复用哈希表的框架并支持…

stm32学习4

学习目录 一.流水灯1.创建文件2.编写相关代码 一.流水灯 1.创建文件 将方法进行分类保存在不同的 .c 文件中&#xff0c;方便复用和寻找&#xff1b; 创建Hardware\LED文件&#xff0c;其中有led.c和led.h文件&#xff0c;用于存放有关LED灯操作的方法&#xff1b; 在User文…

JVM结构图

JVM&#xff08;Java虚拟机&#xff09;是Java编程语言的核心组件之一&#xff0c;负责将Java字节码翻译成机器码并执行。JVM由多个子系统组成&#xff0c;包括类加载子系统、运行时数据区、执行引擎、Java本地接口和本地方法库。 类加载子系统&#xff08;Class Loading Subsy…

mysql之命令行基础指令

一&#xff1a;安装好mysql后&#xff0c;注册好账号密码。 二&#xff1a;在命令行进行登录的指令如下 mysql -u用户名 -p 例如&#xff1a;mysql -uroot -p; 然后按下回车&#xff0c;进入输入密码。 三&#xff1a;基本指令&#xff1a; 1&#xff1a;查看当前账户的所有…

LabVIEW适合开发的软件

LabVIEW作为一种图形化编程环境&#xff0c;主要用于测试、测量和控制系统的开发。以下是LabVIEW在不同应用场景中的适用性和优势。 一、测试与测量系统 LabVIEW在测试与测量系统中的应用广泛&#xff0c;是工程测试领域的主流工具之一。利用其强大的数据采集与处理功能&…

MySQL表的增删改查(CRUD3约束)

这次我们开始先不复习嗷&#xff0c;等到把数据表的删除说完咱们统一&#xff0c;总结书写 1.数据表的删除&#xff1a; 语法&#xff1a; 1. 使用 DROP TABLE 语句删除单个表 基本语法&#xff1a;DROP TABLE [IF EXISTS] table_name; table_name是要删除的表的名称。IF EXIS…

国内首位聋人 Android 软件工程师体验通义灵码,“这真是太棒了”

Hi 大家好&#xff01; 我就是人见人爱、Bug 闪开的通义灵码&#xff01; 上个月&#xff0c;我上线了一项新能力&#xff1a; 体验通义灵码 workspace&#xff1a;轻松分析项目结构&#xff0c;结合代码仓库理解工程、查询问答等 补充说明&#xff1a;当你需要快速了解一个工…

萌熊数据科技:剑指脑机转入,开启科技新篇章

近日&#xff0c;科技圈传来一则令人瞩目的消息&#xff0c;天津萌熊数据科技有限公司和天津一万年科技发展有限公司在全国范围内大力开展AI加生命科学的主体业务&#xff0c;并明确将朝着脑机转入方向深入发展&#xff0c;引发了行业内外的广泛关注。 天津萌熊数据科技有限公司…

OceanBase 安装使用详细说明

OceanBase 安装使用详细说明 一、系统环境要求二、安装OceanBase环境方案一:在线下载并安装all-in-one安装包方案二:离线安装all-in-one安装包安装前的准备工作三、配置OceanBase集群编辑配置文件部署和启动集群连接到集群集群状态和管理四、创建业务租户和数据库创建用户并赋…

MYSQL---TEST5(Trigger触发器Procedure存储过程综合练习)

触发器Trigger 数据库mydb16_trigger创建 表的创建 goods create table goods( gid char(8) primary key, #商品号 name varchar(10), #商品名 price decimal(8,2), #价格 num int&#xff1b;&#xff09; #数量orders create tabl…