Selenium + Pytest自动化测试框架实战(上)

前言

今天呢笔者想和大家来聊聊selenium自动化+ pytest测试框架,在这篇文章里你需要知道一定的python基础——至少明白类与对象,封装继承;一定的selenium基础。这篇文章不会selenium,不会的可以自己去看selenium中文翻译网哟。

一、测试框架简介

测试框架有什么优点呢

    • 代码复用率高,如果不使用框架的话,代码会很冗余
    • 可以组装日志、报告、邮件等一些高级功能
    • 提高元素等数据的可维护性,元素发生变化时,只需要更新一下配置文件
    • 使用更灵活的PageObject设计模式
  • 测试框架的整体目录
  • 目录/文件说明是否为python包common这个包中存放的是常见的通用的类,如读取配置文件是config配置文件目录是logs日志目录page对selenium的方放进行深度的封装是page_element页面元素存放目录page_object页面对象POM设计模式,TestCase所有的测试用例集是utils工具类是script脚本文件conftest.pypytest胶水文件pytest.inipytest配置文件,这样一个简单的框架结构就清晰了。

知道了以上这些我们就开始吧!

我们在项目中先按照上面的框架指引,建好每一项目录。

注意:python包为是的,都需要添加一个__init__.py文件以标识此目录为一个python包。

二、管理时间

首先呢,因为我们很多的模块会用到时间戳,或者日期等等字符串,所以我们先单独把时间封装成一个模块。

然后让其他模块来调用即可。在utils目录新建times.py模块

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import time
import datetime
from functools import wrapsdef timestamp():"""时间戳"""return time.time()def dt_strftime(fmt="%Y%m"):"""datetime格式化时间:param fmt "%Y%m%d %H%M%S"""return datetime.datetime.now().strftime(fmt)def sleep(seconds=1.0):"""睡眠时间"""time.sleep(seconds)def running_time(func):"""函数运行时间"""@wraps(func)def wrapper(*args, **kwargs):start = timestamp()res = func(*args, **kwargs)print("校验元素done!用时%.3f秒!" % (timestamp() - start))return resreturn wrapperif __name__ == '__main__':print(dt_strftime("%Y%m%d%H%M%S"))
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:691998057【暗号:csdn999】

三、添加配置文件

配置文件是项目中必不可少的部分!

将固定不变的信息集中在固定的文件中

3.1conf.py

项目中都应该有一个文件对整体的目录进行管理,我也在这个python项目中设置了此文件。

在项目config目录创建conf.py文件,所有的目录配置信息写在这个文件里面。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import os
from selenium.webdriver.common.by import By
from utils.times import dt_strftimeclass ConfigManager(object):# 项目目录BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 页面元素目录ELEMENT_PATH = os.path.join(BASE_DIR, 'page_element')# 报告文件REPORT_FILE = os.path.join(BASE_DIR, 'report.html')# 元素定位的类型LOCATE_MODE = {'css': By.CSS_SELECTOR,'xpath': By.XPATH,'name': By.NAME,'id': By.ID,'class': By.CLASS_NAME}# 邮件信息EMAIL_INFO = {'username': '1234567890@qq.com',  # 切换成你自己的地址'password': 'QQ邮箱授权码','smtp_host': 'smtp.qq.com','smtp_port': 123}# 收件人ADDRESSEE = ['1234567890@qq.com',]@propertydef log_file(self):"""日志目录"""log_dir = os.path.join(self.BASE_DIR, 'logs')if not os.path.exists(log_dir):os.makedirs(log_dir)return os.path.join(log_dir, '{}.log'.format(dt_strftime()))@propertydef ini_file(self):"""配置文件"""ini_file = os.path.join(self.BASE_DIR, 'config', 'config.ini')if not os.path.exists(ini_file):raise FileNotFoundError("配置文件%s不存在!" % ini_file)return ini_filecm = ConfigManager()
if __name__ == '__main__':print(cm.BASE_DIR)

注意:QQ邮箱授权码怎么生成自己去百度

这个conf文件我模仿了Django的settings.py文件的设置风格,但是又有些许差异。

在这个文件中我们可以设置自己的各个目录,也可以查看自己当前的目录。

遵循了约定:不变的常量名全部大写,函数名小写。看起来整体美观。

3.2config.ini

在项目config目录新建一个config.ini文件,里面暂时先放入我们的需要测试的URL

[HOST]
HOST = https://www.baidu.com

四、读取配置文件

配置文件创建好了,接下来我们需要读取这个配置文件以及使用里面的信息。

我们在common目录中新建一个readconfig.py文件

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import configparser
from config.conf import cmHOST = 'HOST'class ReadConfig(object):"""配置文件"""def __init__(self):self.config = configparser.RawConfigParser()  # 当有%的符号时请使用Raw读取self.config.read(cm.ini_file, encoding='utf-8')def _get(self, section, option):"""获取"""return self.config.get(section, option)def _set(self, section, option, value):"""更新"""self.config.set(section, option, value)with open(cm.ini_file, 'w') as f:self.config.write(f)@propertydef url(self):return self._get(HOST, HOST)ini = ReadConfig()if __name__ == '__main__':print(ini.url)

可以看到我们用python内置的configparser模块对config.ini文件进行了读取。

对于url值的提取,我使用了高阶语法@property属性值,写法更简单。

五、记录操作日志

日志,大家应该都很熟悉这个名词,就是记录代码中的动作。

在utils目录中新建logger.py文件。

这个文件就是我们用来在自动化测试过程中记录一些操作步骤的。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import logging
from config.conf import cmclass Log:def __init__(self):self.logger = logging.getLogger()if not self.logger.handlers:self.logger.setLevel(logging.DEBUG)# 创建一个handle写入文件fh = logging.FileHandler(cm.log_file, encoding='utf-8')fh.setLevel(logging.INFO)# 创建一个handle输出到控制台ch = logging.StreamHandler()ch.setLevel(logging.INFO)# 定义输出的格式formatter = logging.Formatter(self.fmt)fh.setFormatter(formatter)ch.setFormatter(formatter)# 添加到handleself.logger.addHandler(fh)self.logger.addHandler(ch)@propertydef fmt(self):return '%(levelname)s\t%(asctime)s\t[%(filename)s:%(lineno)d]\t%(message)s'log = Log().loggerif __name__ == '__main__':log.info('hello world')

在终端中运行该文件,就看到命令行打印出了:

INFO	2022-06-15 16:00:05,467	[logger.py:38]	hello world

然后在项目logs目录下生成了当月的日志文件。

六、简单理解POM模型

由于下面要讲元素相关的,所以首先理解一下POM模型

Page Object模式具有以下几个优点。

该观点来自 《Selenium自动化测试——基于Python语言》

  • 抽象出对象可以最大程度地降低开发人员修改页面代码对测试的影响, 所以, 你仅需要对页
    面对象进行调整, 而对测试没有影响;
  • 可以在多个测试用例中复用一部分测试代码;
  • 测试代码变得更易读、 灵活、 可维护

Page Object模式图

  • basepage ——selenium的基类,对selenium的方法进行封装
  • pageelements——页面元素,把页面元素单独提取出来,放入一个文件中
  • searchpage ——页面对象类,把selenium方法和页面元素进行整合
  • testcase ——使用pytest对整合的searchpage进行测试用例编写

通过上图我们可以看出,通过POM模型思想,我们把:

  • selenium方法
  • 页面元素
  • 页面对象
  • 测试用例

以上四种代码主体进行了拆分,虽然在用例很少的情况下做会增加代码,但是当用例多的时候意义很大,代码量会在用例增加的时候显著减少。我们维护代码变得更加直观明显,代码可读性也变得比工厂模式强很多,代码复用率也极大的得到了提高。

这篇文章暂时到这里哟,后面会接着讲的哟。

下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

最后: 可以在公众号:程序员小濠 ! 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

六西格玛管理培训公司:事业进阶的充电站,助你冲破职场天花板!

六西格玛,源于制造业,却不仅仅局限于制造业。它是一种以数据为基础、以顾客为中心、以流程优化为手段的全面质量管理方法。通过六西格玛管理,企业可以系统性地识别并解决运营过程中的问题,提高产品和服务的质量,降低成…

导航app为什么知道还有几秒变绿灯?

在使用地图导航app行驶至信号灯的交叉路口时,这些应用程序会贴心地告知用户距信号灯变化还有多少秒,无论是即将转为绿灯还是红灯。这一智能化提示不仅使得驾驶员能适时做好起步或刹车的准备,有效缓解了因等待时间不确定而产生的焦虑情绪&…

GBPC2510-ASEMI工业电源专用GBPC2510

编辑:ll GBPC2510-ASEMI工业电源专用GBPC2510 型号:GBPC2510 品牌:ASEMI 封装:GBPC-4 最大重复峰值反向电压:1000V 最大正向平均整流电流(Vdss):25A 功率(Pd):中小功率 芯片个数&#x…

分布式锁之RedissonLock

什么是Redisson? 俗话说他就是看门狗,看门狗机制是一种用于保持Redis连接活跃性的方法,通常用于分布式锁的场景。看门狗的工作原理是:当客户端获取到锁之后,会对Redis中的一个特定的键设置一个有限的过期时间&#xff…

[附源码]传世手游_玲珑传世_GM_安卓搭建教程

本教程仅限学习使用,禁止商用,一切后果与本人无关,此声明具有法律效应!!!! 教程是本人亲自搭建成功的,绝对是完整可运行的,踩过的坑都给你们填上了。 如果你是小白也没…

C++ 509. 斐波那契数

文章目录 一、题目描述二、参考代码 一、题目描述 示例 1: 输入:n 2 输出:1 解释:F(2) F(1) F(0) 1 0 1 示例 2: 输入:n 3 输出:2 解释:F(3) F(2) F(1) 1 1 2 示例 3…

设计模式——访问者模式(Visitor)

访问者模式(Visitor Pattern)是一种将数据操作与数据结构分离的设计模式。这种模式适用于数据结构相对稳定,而操作算法经常改变的情况。访问者模式将数据结构(稳定的部分)中的元素(Element)的访…

C语言题目:一元二次方程

题目描述 解一元二次方程ax^2bxc0的解。 输入格式 a,b,c的值。 输出格式 输出两个解,按照大小顺序输出,一个解时需要打印两次,不用考虑无解问题,保留两位小数 样例输入 1 5 -2样例输出 0.37 -5.37 代码解析 首先&#xff0…

了解进程和线程

一、进程和线程 类比: 一个工厂,至少有一个车间,一个车间中至少有一个工人,最终是工人在工作。 一个程序,至少有一个进程,一个进程中至少有一个线程,最终是线程在工作。 进程:是计…

C#正则表达式,提取信息使用

正则表达式简介 在C#中,正则表达式(Regular Expression,通常简写为regex或regexp)是一种功能强大的文本处理工具,它使用特定的字符序列来定义搜索模式,从而实现对文本的高效搜索、匹配和替换操作。正则表达…

乡村振兴与乡村旅游深度融合:依托乡村自然和文化资源,发展乡村旅游产业,促进农民增收致富,打造特色美丽乡村

目录 一、引言 二、乡村振兴与乡村旅游的内在联系 三、依托乡村自然和文化资源发展乡村旅游产业 (一)挖掘乡村自然资源优势,打造特色旅游品牌 (二)挖掘乡村文化资源内涵,丰富旅游活动内容 四、促进农…

新手做视频号电商,做什么样的产品好卖?适合不会选类目的新手看

大家好,我是电商花花,专注做电商的花花。 视频号现在的发展可以说是非常好的,拥有着空前的市场和流量,随着视频号小店新项目对电商的冲击,让更多创业者和新手商家开始涌入视频号电商的行列。 想要在新项目中抢占流量…

【客户案例】禅道软件助力长虹新网实现研发项目管理创新

四川长虹新网科技有限责任公司(以下简称长虹新网)深耕全球运营商市场二十多年,具备行业领先的软硬件研发、制造、全球化市场营销能力,持续服务国内外200多家主流电信及广电运营商、垂直行业服务商,与合作伙伴共同成长。…

Windows11系统安装Mysql8之后,启动服务net start mysql报错“服务没有响应控制功能”的解决办法

问题 系统环境:Windows11 数据库版本:Mysql8 双击安装,一路下一步,完成,很顺利,但是开启服务后 net start mysql 报错: 服务没有响应控制功能。 请键入 NET HELPMSG 2186 以获得更多的帮助 不…

【项目001】运维工程师项目实践:高可用性云基础设施部署与升级项目

目录 项目名称 项目背景 项目目标 项目成果 我的角色与职责 我主要完成的工作内容 本次项目涉及的技术 本次项目遇到的问题与解决方法 本次项目中可能被面试官问到的问题 1、什么是ELK? 2、什么是Elasticsearch、Logstash 和Kibana? 3、ELK 三…

echarts树图 改文本显示的地方的样式

树图改文本显示的时候的样式 虽然有点越改越丑 其中有一些失败的尝试 forammter 无法识别html元素 所以对于tooptips有用的html元素定义获取返回在这里写的话是不生效的 rich配置项里面的backgroundColor官方说支持 html元素和canvas元素 已经图片url 没有详细试验 官网地址 h…

【chisel】如何用chisel写一个上升沿检测程序

自定义上升沿检测 class RisingEdgeDetector extends Module {val io IO(new Bundle {val inSig Input(Bool())val outSig Output(Bool())val clock Input(Clock())})// 定义 risingedge 函数def risingedge(x: Bool): Bool x && !RegNext(x)// 使用 risingedge …

代码签名证书的重要作用及申请途径

代码签名技术是一种确保软件完整性和来源可信度的安全措施。它通过数字证书和加密算法为软件代码或可执行文件加上一个“签名”,以此验证软件未被篡改,并确认其来源于可信赖的开发者。 一、代码签名证书的重要作用 1、提高下载率和安装率:用…

Linux提权--Rsync(未授权访问) Docker 组挂载

免责声明:本文仅做技术学习与交流... 目录 Rsync(未授权访问) 介绍: 靶场及过程: 提权过程: Docker 组挂载 原理: 复现: 利用: 具体操作: 1-确定是否有docker服务 2-查看用户是否在docker组里面 3-执行命…

包管理工具npm、cnpm、yarn、NVM

文章目录 npmnpm基本使用npm搜索包生产环境与开发环境开发依赖与生产依赖全局安装环境变量Path安装包依赖安装指定版本的包、删除依赖配置命令别名 cnpm安装操作命令:配置 yarnyarn安装及常用命令yarn 配置淘宝镜像 NVM使用常用命令 扩展内容npm和yarn的选择npm发布…