【pytest】tep环境变量、fixtures、用例三者之间的关系
tep是一款测试工具,在pytest测试框架基础上集成了第三方包,提供项目脚手架,帮助以写Python代码方式,快速实现自动化项目落地。
在tep项目中,自动化测试用例都是放到tests目录下的,每个.py文件相互独立,没有依赖,1个文件即1条用例,彼此分离。
虽然用例也能相互引用,但是除非万不得已,一般不建议这么做,牵一发动全身,后期维护困难。
用例的代码编写,思路是从上往下的,和pytest/unittest/script常规写法无异,不会有学习成本,一般也不会有问题。有成本有问题的可能是环境变量和fixtures,因为tep做了封装,提供了依赖注入的共享方式,fixture又是pytest较难理解的知识点,所以有必要通过本文来讲讲tep环境变量、fixtures、用例三者之间的关系,帮助理解,以便更灵活顺手的借助tep实现pytest自动化项目。
假如不用环境变量和fixtures
假如不用环境变量和fixtures,是完全可以的!比如,在tests
下新建脚本login_test.py
:
from tep.client import requestdef test():response = request("post",url="https://qa.com/api/users/login",headers={"Content-Type": "application/json"},json={"username": "admin","password": "123456",})assert response.status_code < 400
请求接口https://qa.com/api/users/login
,断言响应状态码小于400。问题来了:url
固定,假如需要切换两个环境qa
和release
,该怎么办?
参数化
无论是做自动化测试还是性能测试,都会接触到参数化这个词。它是指把代码中的固定数据(硬编码)定义成变量,让每次运行时数据不一样,固定数据变为动态数据。动态数据的来源是变量、数据库、外部文件等。动态数据的类型一般是常量的字符串,也可以是函数,比如JMeter的函数助手,也可以是依赖注入,比如pytest的fixture。
依赖注入的fixture
“依赖注入是控制反转(IoC, Inversion of Control)的一种技术形式”,这句话出自维基百科,我也不知道什么意思,画个图简单表达下:
意思是,给client一个injector,client不需要做什么,就能用到service。
pytest的fixture实现了依赖注入,允许我们在不修改测试代码的情况下,引入fixture来额外添加一些东东。
对于url来说,域名是需要做参数化的,不同环境域名不同,所以tep把它做成了fixture,通过函数参数引入:
from tep.client import request
from tep.fixture import *def test(url): # 引入fixtureresponse = request("post",url=url("/api/users/login"),headers={"Content-Type": "application/json"},json={"username": "admin","password": "123456",})assert response.status_code < 400
tep.fixture.url
定义如下:
@pytest.fixture(scope="session")
def url(env_vars):def domain_and_uri(uri):if not uri.startswith("/"):uri = "/" + urireturn env_vars.domain + urireturn domain_and_uri
如果一眼就看懂了,恭喜你,如果一眼就看懵了,没关系。我会花功夫把它讲明白,它很关键!
把fixture当变量看
虽然从定义上看,fixture是用def
关键字定义的函数,但是理解上把它看做变量就可以了。比如:
import pytest@pytest.fixture
def name():return "dongfanger"
一般函数的用法是函数名加小括号,通过name()
才能得到"dongfanger"
。fixture不一样,以上定义可以理解为:
name = "dongfanger"
把"dongfanger"
赋值给name
,fixture名 = return值。通过变量name
就得到"dongfanger"
了。
既然是变量,那么就能随便赋值,str
、function
、class
、object
都行。比如在fixture内部定义个函数:
import pytest@pytest.fixture
def who():def get_name():return "dongfanger"return get_name
理解为把函数名get_name赋值给fixture名变量:
who = get_name
get_name是个函数名,需要加小括号get_name()才能得到"dongfanger"。who也必须通过who()才能得到"dongfanger"。再看tep.fixture.url是不是清楚些了:
@pytest.fixture(scope="session")
def url(env_vars):def domain_and_uri(uri):if not uri.startswith("/"):uri = "/" + urireturn env_vars.domain + urireturn domain_and_uri
理解为把函数名domain_and_uri
赋值给fixture名变量:
url = domain_and_uri
使用时通过url("/api")
得到域名和uri拼接后的结果。
第2行的def url(env_vars):
也有一个参数env_vars
,接下来继续解释。
fixture参数是其他fixture
fixture的参数只能是其他fixture。比如:
import pytest@pytest.fixture
def chinese_name():return "东方er"@pytest.fixture
def english_name(chinese_name):return "dongfanger"
调用english_name
,pytest会先执行参数里的其他fixture chinese_name
,然后执行自己english_name
。
如果把tep.fixture.url
拆成两步来看,就很清晰了,第一步:
@pytest.fixture(scope="session")
def url(env_vars):func = Nonereturn func
第二步:
@pytest.fixture(scope="session")
def url(env_vars):func = Nonedef domain_and_uri(uri):if not uri.startswith("/"):uri = "/" + urireturn env_vars.domain + urifunc = domain_and_urireturn func
环境变量
tep.fixture.url
的参数是另外一个fixture env_vars
环境变量,它的定义如下:
from tep.fixture import *@pytest.fixture(scope="session")
def env_vars(config):class Clazz(TepVars):env = config["env"]"""Variables define start"""# Environment and variablesmapping = {"qa": {"domain": "https://qa.com",},"release": {"domain": "https://release.com",}# Add your environment and variables}# Define properties for auto displaydomain = mapping[env]["domain"]"""Variables define end"""return Clazz()
只看中间注释"""Variables define start"""到"""Variables define end"""部分即可。url参数化的域名就在这里,mapping字典建立了环境和变量之间的映射,根据不同的环境key,获取不同的变量value。
config fixture的作用是读取conf.yaml文件里面的配置。
参数化的方式很多,JMeter提供了4种参数化方式,tep的fixture env_vars
借鉴了JMeter的用户自定义变量:
env_vars.put()
和env_vars.get()
借鉴了JMeter BeanShell的vars.put()
和vars.get()
。
实例:测试多个网址
讲到最后,形成了思路,通过实际的例子,看看环境变量、fixtures、用例是怎么用起来的,加深下印象。假如qa
环境有2个网址,学校端和机构端,脚本都需要用到。
第一步修改env_vars
,编辑fixture_env_vars.py
:
"""Variables define start"""# Environment and variablesmapping = {"qa": {"domain": "https://qa.com","domain_school": "https://school.qa.com", # 新增"domain_org": "https://org.qa.com" # 新增},"release": {"domain": "https://release.com","domain_school": "https://school.release.com" # 新增"domain_org": "https://org.release.com" # 新增}# Add your environment and variables}# Define properties for auto displaydomain = mapping[env]["domain"]domain_school = mapping[env]["domain_school"] # 新增domain_org = mapping[env]["domain_org"] # 新增"""Variables define end"""
添加了6行代码,定义了env_vars.domain_school
和env_vars.domain_org
。
第二步定义fixtures,新建fixture_url.py
:
@pytest.fixture(scope="session")
def url_school(env_vars):def domain_and_uri(uri):if not uri.startswith("/"):uri = "/" + urireturn env_vars.domain_school + urireturn domain_and_uri@pytest.fixture(scope="session")
def url_org(env_vars):def domain_and_uri(uri):if not uri.startswith("/"):uri = "/" + urireturn env_vars.domain_org + urireturn domain_and_uri
参照tep.fixture.url,修改env_vars.domain为env_vars.domain_school和env_vars.domain_org,新增了2个fixture url_school和url_org。
更进一步,也许会定义fixture login_school和login_org,灵活选择。
小结
本文循序渐进的讲解了tep环境变量、fixtures和用例之间的关系,重点对tep.fixture.url进行了解释,只要理解了它,整体关系就很清楚了。之所以要用fixture,原因一是多人协作共享,我们需要用别人写好的函数,复用返回值,有些同学习惯定义函数参数,参数不变还好,万一哪天改了,别人引用的用例会全部报错,fixture很好的限制了这一点,它默认是不能传参的,虽然可以通过定义内部函数来实现传参,但是并不推荐这么做,宁愿增加冗余代码,定义多个fixture,也比代码耦合度高好一些。原因二是import的问题,pytest会自动查找conftest.py里的fixture,tep会进一步自动查找fixtures下的fixture导入到conftest.py,不需要import就能使用,减少了import代码,避免了可能会出现的循环导入问题。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
软件测试面试小程序
被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!
涵盖以下这些面试题板块:
1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux
6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
相关文章:

【pytest】tep环境变量、fixtures、用例三者之间的关系
tep是一款测试工具,在pytest测试框架基础上集成了第三方包,提供项目脚手架,帮助以写Python代码方式,快速实现自动化项目落地。 在tep项目中,自动化测试用例都是放到tests目录下的,每个.py文件相互独立&…...

风控引擎如何快速添加模型,并实时了解运行状态?
目录 风控模型的主要类型 风控引擎如何管理模型? 模型就是基于目标群体的大规模采样数据,挖掘出某个实际问题或客观事物的现象本质及运行规律,利用抽象的概念分析存在问题或风险,计算推演出减轻、防范问题或风险的对策过程&…...

一文读懂|内核顺序锁
Linux 内核有非常多的锁机制,如:自旋锁、读写锁、信号量和 RCU 锁等。本文介绍一种和读写锁比较相似的锁机制:顺序锁(seqlock)。 顺序锁与读写锁一样,都是针对多读少写且快速处理的锁机制。而顺序锁和读写…...
openproject在docker下的安装
官方指引:https://www.openproject.org/docs/installation-and-operations/installation/docker/ 网友指引:https://blog.csdn.net/joefive/article/details/119409550 建个自己的数据文件夹: sudo mkdir -p /var/lib/openproject/{mydata…...

React【React是什么?、创建项目 、React组件化、 JSX语法、条件渲染、列表渲染、事件处理】(一)
文章目录 React是什么? 为什么要学习React React开发前准备 创建React项目 React项目结构简介 React组件化 初识JSX 渲染JSX描述的页面 JSX语法 JSX的Class与Style属性 JSX生成的React元素 条件渲染(一) 条件渲染 ࿰…...

Ubuntu系统下配置 Qt Creator 输入中文、配置软件源的服务器地址、修改Ubuntu系统时间
上篇介绍了Ubuntu系统下搭建QtCreator开发环境。我们可以发现安装好的QtCreator不能输入中文,也没有中文输入法供选择,这里需要进行设置。 文章目录 1. 配置软件源的服务器地址2. 先配置Ubuntu系统语言,设置为中文3. 安装Fcitx插件ÿ…...

Ab3d.PowerToys 11.0.8614 Crack
版本 11.0.8614 修补程序 使用 MouseCameraController 移动相机时防止旋转 FreeCamera。 版本 11.0.8585 重大更改:由于专利问题删除了 ViewCubeCameraController - 请联系支持人员以获取更多信息以及如果您想继续使用此控件。添加了 CameraNavigationCircles 控件…...

汽车3D HMI图形引擎选型指南【2023】
推荐:用 NSDT编辑器 快速搭建可编程3D场景 2002年,电影《少数派报告》让观众深入了解未来。 除了情节的核心道德困境之外,大多数人都对它的技术着迷。 我们看到了自动驾驶汽车、个性化广告和用户可以无缝交互的 3D 计算机界面。 令人惊讶的是…...

Stable Diffusion stable-diffusion-webui开发笔记
https://lexica.art/ lexica.art 该网站拥有数百万Stable Diffusion案例的文字描述和图片,可以为大家提供足够的创作灵感。可以提供promt灵感 https://civitai.com/ Civitai是一个聚集AI绘图爱好者的社区,在此网站上有许多定制化的模型,特…...

利用MQ实现mysql与elasticsearch数据同步
流程 1.声明exchange、queue、RoutingKey 2. 在hotel-admin中进行增删改(SQL),完成消息发送 3. 在hotel-demo中完成消息监听,并更新elasticsearch数据 4. 测试同步 1.引入依赖 <!--amqp--> <dependency><groupId&…...

linux免密登录最简单--图文详解
最简单的免密登录 1.A电脑生成秘钥 ssh-keygen -t rsa 2.A电脑将秘钥传给B电脑 ssh-copy-id root192.168.1.129 #将秘钥直接传给B电脑 需要输入B电脑的密码,可以看到成功。 3.测试 同理:如果B->A也需要免密登录,统一的操作。 大功告…...
HTTP/1.1协议中的请求报文
2023年8月30日,周三上午 目录 概述请求报文示例详述 概述 HTTP/1.1协议的请求报文由以下几个部分组成: 请求行(Request Line)请求头部(Request Headers)空行(Blank Line)请求体&a…...

攻防世界-Hear-with-your-Eyes
原题 解题思路 是一个没有后缀的文件,题目提示要用眼睛看这段音频,notepad打开文件,没什么东西。 加后缀zip再解压看看。 使用Audacity打开音频文件...
ZED相机获取图像python
import pyzed.sl as sl import cv2 import numpy as np import osclass CameraZed2:def __init__(self,resolutionNone,fps30,depthMode None):self.zed sl.Camera()self.input_type sl.InputType()self.init_params sl.InitParameters(input_tself.input_type)# 设置分辨率…...
Oracle系列之--Profile
Oracle系列之--Profile_oracle profile_楼兰过客的博客-CSDN博客...

学习Bootstrap 5的第四天
目录 表格 基础表格 实例 条纹表格 实例 带边框表格 实例 有悬停效果的行 实例 黑色/深色表格 实例 黑色/深色条纹表格 实例 可悬停的黑色/深色表格 实例 无边框表格 实例 上下文类 可用的上下文类: 实例 表头颜色 实例 小型表格 实例 响应…...

喜报 | 再度中标南网项目!AR 开启电力远程运维新智慧
近日,中国南方电网官网发布《2023年南方电网数字平台科技 (广东)有限公司物资品控远程协助软件采购项目中标公告》,ALVA Systems 凭借 ALVA Rainbow 创新应用竞得此标。 随着相关技术的逐步成熟,基础问题远程化解决已经在工业领域广泛应用。 …...
3.使用IDE的优点
IDE是集成开发环境:Integrated Development Environment的缩写。 1、优点 使用IDE的好处在于,可以把编写代码、组织项目、编译、运行、调试等放到一个环境中运行,能极大地提高开发效率。 IDE提升开发效率主要靠以下几点: 编辑器…...

ShopXO商城系统文件上传0Day代审历程
Git仓库: https://github.com/gongfuxiang/shopxo简介: 两天攻防中,某政局内网横向发现多网段服务器,该服务器搭建了ShopXO商城系统(后来发现是开发临时搭建的,准备做二开用的)。结果花了30来秒审了个垃圾Day拿下该服…...

【java】【项目实战】[外卖十二]【完结】项目优化(前后端分离开发)
目录 一、问题说明 二、前后端分离开发 1、介绍 2、开发流程 3、前端技术栈 三、Yapi 1、介绍 2、部署 3、使用 3.1 添加项目编辑 3.2 添加分类编辑 3.3 添加接口 3.4 运行 3.5 导出接口 3.6 导入数据 四、Swagger 1、介绍 2、使用方式 2.1 pom 2.2 导入…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...