Pytest系列-fixture的详细使用和结合conftest.py的详细使用(3)

介绍

前面一篇讲了setup、teardown可以实现在执行用例前或结束后加入一些操作,但这种都是针对整个脚本全局生效的。
Fixture是pytest的非常核心功能之一,在不改变被装饰函数的前提下对函数进行功能增强,经常用于自定义测试用例前置和后置工作,更强大灵活。

一 、Fixture的优势

  • fixture命名方式灵活,不局限于 setup 和teardown 那几个命名规则
  • conftest.py 配置里可以实现数据共享,不需要 import就能够自动搜索需要的fixture
  • fixture 配置不同的参数可以轻松实现跨文件共享前置、session会话共享

二、fixture工作原理

  • 在普通函数上使用@Pytest.fixture()装饰器,声明函数为一个fixture函数
  • 如果测试用例函数的参数列表中存在fixture的函数名或者使用@pytest.mark.usefixtures(fixture_name)
  • 在测试执行阶段,pytest执行用例之前执行fixture函数功能
  • 如果fixture装饰的函数无返回值,相当于用例前置操作,否则相当于传参
  • 如果fixture设置了后置操作,则用例执行完成后进行执行

三、fixture的参数

@pytest.fixture(scope="function",params=None,autouse=True,ids=None,name=None)
def test():print("fixture初始化的参数")

参数

1、scope:可以理解成fixture的作用域。
(1) function:在函数之前和之后执行。函数测试用例时使用时需要引用参数 def test(seif,fixtures_def)

  • 手动调用的方式是在测试用例的参数里面加入 fixture的名称。
  • 如果说fixture有通过return或yield返回值的话,那么可以把这个值传递到测试用例中。值是通过固件的名字传递的。

参考用例:

import pytest@pytest.fixture(scope="function",autouse=False)
def test_fixture():print("fixture初始化的参数")return "success"   #后面不能有其他语句#yield "success"   #后面可以有其他语句#print("参数后置")class TestFixture:def test_one(self):print("测试用例1")def test_two(self,test_fixture):print("测试用例2")print(test_fixture)def test_three(self):print("测试用例1")if __name__ == '__main__':pytest.main()

执行结果:
在这里插入图片描述

(2) class:在类之前和之后执行。

  • 手动调用的方式是在类的上面加@pytest.mark.usefixtures(“login”)装饰器

参考用例:

import pytest@pytest.fixture(scope="class",autouse=False)
def test_fixture():print("fixture初始化的参数")yield "success"   #后面可以有其他语句print("参数后置")@pytest.mark.usefixtures("test_fixture")
class TestFixture:def test_one(self):print("测试用例1")def test_two(self,test_fixture):print("测试用例2")print(test_fixture)class TestStudy:def test_three(self):print("测试用例3")if __name__ == '__main__':pytest.main()

执行结果:
在这里插入图片描述

(3) module:每一个.py文件调用一次
参考用例:

import pytest@pytest.fixture(scope="module",autouse=False,)
def test_fixture():print("fixture初始化的参数")yield "success"print("参数后置")# 通过参数方式使用fixture
def test_01(test_fixture):print("类外面的测试用例")class TestFixture:def test_one(self):print("测试用例1")def test_two(self,test_fixture):print("测试用例2"+test_fixture)if __name__ == '__main__':pytest.main()

执行结果:
在这里插入图片描述

(4) package/session:在整个项目会话之前和之后,即开始执行pytest到结束测试一般用于打开浏览器、启动APP、登录等操作。会结合conftest.py文件来实现

2、autouse:默认False,需要用例手动调用该fixture;如果是True,所有作用域内的测试用例都会自动调用该fixture,无需传入fixture函数名,作用范围跟着scope走(注意使用)。

3、param:实现参数化

  • 如何把值传到Fixture是通过fixture函数的参数里面加入request来接收参数。然后通过request.param来取值。(这里的param没有s)
@pytest.fixture(scope="function",autouse=False,params=read_yaml())
def test_fixture(request):print("fixture初始化的参数")yield (request.param)print("参数后置")

参考用例:

import pytest#读取数据文件
def read_yaml():return ['cehsi','houduan','qianduan']#return [{'a':'b'},{'c','d'}]@pytest.fixture(scope="function",autouse=False,params=read_yaml())
def test_fixture(request):print("fixture初始化的参数")yield request.paramprint("参数后置")class TestFixture:def test_one(self):print("测试用例1")def test_two(self,test_fixture):print("测试用例2"+test_fixture)#print("测试用例2"+str(test_fixture)) #数据是字典的话需要强转if __name__ == '__main__':pytest.main()

执行结果:
在这里插入图片描述
5、ids:不单独使用,需要与params配合使用,一对一关系,作用是对参数起别名。
参考用例:

@pytest.fixture(scope="function",autouse=False,params=read_yaml(),ids=['a','b','c'])
def test_fixture(request):print("fixture初始化的参数")yield request.paramprint("参数后置")

执行结果:
在这里插入图片描述

5、name:作用给Fixture取别名,用来区分不同的使用。
【特别注意】:一旦使用别名之后,那么fixture的名称就不能用了。只能用别名。
参考用例:

import pytest#读取数据文件
def read_yaml():return ['cehsi','houduan','qianduan']#return [{'a':'b'},{'c','d'}]@pytest.fixture(scope="function",autouse=False,params=read_yaml(),ids=['a','b','c'],name='abc')
def test_fixture(request):print("fixture初始化的参数")yield request.paramprint("参数后置")class TestFixture:def test_one(self):print("测试用例1")def test_two(self,abc):print("测试用例2"+abc)#print("测试用例2"+str(test_fixture)) #数据是字典的话需要强转if __name__ == '__main__':pytest.main()

注意

@pytest.mark.usefixtures():

  • 在类声明上面加 @pytest.mark.usefixtures() ,代表这个类里面所有测试用例都会调用该fixture
  • 可以叠加多个 @pytest.mark.usefixtures() ,先执行的放底层,后执行的放上层
  • 可以传多个fixture参数,先执行的放前面,后执行的放后面
  • 如果fixture有返回值,用 @pytest.mark.usefixtures() 是无法获取到返回值的,必须用传参的方式(方式一)

四、 Fixture中yield来实现teardown

用fixture实现teardown并不是一个独立的函数,而是用 yield 关键字来开启teardown操作,使用可参考上面的测试用例。

yield注意事项

  • 如果yield前面的代码,即setup部分已经抛出异常了,则不会执行yield后面的teardown内容
  • 如果测试用例抛出异常,yield后面的teardown内容还是会正常执行

yield+with的结合

# 官方例子
@pytest.fixture(scope="module")
def smtp_connection():with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp_connection:yield smtp_connection  # provide the fixture value

smtp_connection 连接将测试完成执行后已经关闭,因为 smtp_connection 对象自动关闭时, with 语句结束。

五、 addfinalizer 终结函数

@pytest.fixture(scope="module")
def test_addfinalizer(request):# 前置操作setupprint("==再次打开浏览器==")test = "test_addfinalizer"def fin():# 后置操作teardownprint("==再次关闭浏览器==")request.addfinalizer(fin)# 返回前置操作的变量return testdef test_anthor(test_addfinalizer):print("==最新用例==", test_addfinalizer)

注意事项

  • 如果 request.addfinalizer() 前面的代码,即setup部分已经抛出异常了,则不会执行 request.addfinalizer() 的teardown内容(和yield相似,应该是最近新版本改成一致了)
  • 可以声明多个终结函数并调用

六、Fixture结合conftest.py的使用

conftest.py的介绍

1、pytest会默认读取conftest.py里面的所有fixture
2、 conftest.py是专门用于存放fixture的配置文件。名称是固定的,不能变。
3、在 conftest.py文件里面所有的方法在调用时都不需要导包,pytest会自动查找。
5、 conftest.py文件可以有多个,并且多个 conftest.py文件里面的多个 fixture可以被一个用例调用
6、conftest.py只对同一个package下的所有测试用例生效

conftest.py文件一般写在项目的根路径下面,文件名不要写错

参考用例:
testcase.py

# 通过参数方式使用fixture
def test_01(abc):print("类外面的测试用例")class TestFixture:def test_one(self):print("测试用例1")def test_two(self,abc,sd):print("测试用例2"+abc+sd)if __name__ == '__main__':pytest.main()

conftest.py


import pytest@pytest.fixture(scope="function",autouse=False,name='abc')
def test_fixture():print("fixture初始化的参数")yield "success"print("参数后置")@pytest.fixture(scope="function",autouse=False,name='sd')
def test_study():print("多个fixture初始化的参数")yieldprint("多个参数后置")

执行结果:
在这里插入图片描述

七、Fixture的优先级

  • 较高 scope 范围的fixture(session)在较低 scope 范围的fixture( function 、 class )【session > package > module > class > function】
  • 具有相同作用域的fixture遵循测试函数中声明的顺序,并遵循fixture之间的依赖关系【在fixture_A里面依赖的fixture_B优先实例化,然后到fixture_A实例化】

八、setup、teardown、setup_class、teardown_class、fixture、conftest优先级

会话:fixture的session级别的优先级最高。

类:fixture的class级别的优先级最高。
类:setup_class

函数:fixture的function级别的优先级最高。
函数:setup

九、总结Pytest的执行过程

1、查询当前目录下的 conftest.py 文件;
2、查询当前目录下的 pytest.ini 文件,找到测试用例的位置;
3、查询用例目录下的 conftest.py 文件;
4、查询py文件中是否有setup_class、teardown_class;
5、再根据 pytest.ini 文件的测试用例规则去查询用例并执行。

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

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

相关文章

恭贺弘博创新2023下半年软考(中/高级)认证课程顺利举行

为迎接2023年下半年软考考试,弘博创新于2023年9月2日举行了精品的软考中/高级认证课程,线下线上学员都积极参与学习。 在课程开始之前,弘博创新的老师为学员们提供了详细的学习资料和准备建议,以确保学员们在课程中能够跟上老师的…

【实践篇】Redis最强Java客户端(三)之Redisson 7种分布式锁使用指南

文章目录 0. 前言1. Redisson 7种分布式锁使用指南1.1 简单锁:1.2 公平锁:1.3 可重入锁:1.4 红锁:1.5 读写锁:1.6 信号量:1.7 闭锁: 2. Spring boot 集成Redisson 验证分布式锁3. 参考资料4. 源…

LeetCode 49题: 字母异位词分组

题目 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat&qu…

Linux中的软件管家——yum

目录 ​编辑 一,软件安装的方式 二,对yum的介绍 1.yum的作用 2,yum的库 三,yum下载软件的操作 1.yumlist 2.yuminstall 3.yumremove 四,yum源的转换 一,软件安装的方式 软件安装的方式大概分为三种…

【韩顺平】Linux基础

目录 1.网络连接三种方式 1.1 桥接模式:虚拟系统可以和外部系统通讯,但是容易造成IP冲突【1-225】 1.2 NAT模式:网络地址转换模式。虚拟系统可以和外部系统通讯,不造成IP冲突。 1.3 主机模式:独立的系统。 2.虚拟机…

C# PSO 粒子群优化算法 遗传算法 随机算法 求解复杂方程的最大、最小值

复杂方程可以自己定义,以下是看别人的题目,然后自己来做 以下是计算结果 private void GetMinResult(out double resultX1, out double min){double x1, result;Random random1 new Random(DateTime.Now.Millisecond* DateTime.Now.Second);min 99999…

C语言柔性数组详解:让你的程序更灵活

柔性数组 一、前言二、柔性数组的用法三、柔性数组的内存分布四、柔性数组的优势五、总结 一、前言 仔细观察下面的代码,有没有看出哪里不对劲? struct S {int i;double d;char c;int arr[]; };还有另外一种写法: struct S {int i;double …

软件与系统安全复习

软件与系统安全复习 课程复习内容 其中 软件与系统安全基础 威胁模型 对于影响系统安全的所有信息的结构化表示 本质上,是从安全的视角解读系统与其环境 用于理解攻击者 什么可信、什么不可信攻击者的动机、资源、能力;攻击造成的影响 具体场景…

了解被测系统(二)接入链路--包括域名解析和Nginx代理

目录 一、接入链路示例 二、域名解析过程 1、相关概念 1.1、域的结构 1.2、DNS是什么? 1.3、DNS根域名服务器 1.4、顶级域名服务器 1.5、权威域名服务器 2、域名解析过程 2.1、检查Hosts文件 2.2、检查本地DNS缓存 2.3、DNS解析--本地DNS服务器 2.4、D…

后端SpringBoot+前端Vue前后端分离的项目(二)

前言:完成一个列表,实现表头的切换,字段的筛选,排序,分页功能。 目录 一、数据库表的设计 ​编辑二、后端实现 环境配置 model层 mapper层 service层 service层单元测试 controller层 三、前端实现 interface接…

合宙Air724UG LuatOS-Air LVGL API控件-滑动条 (Slider)

滑动条 (Slider) 滑动条看起来和进度条是有些是有些像,但不同的是滑动条可以进行数值选择。 示例代码 -- 回调函数 slider_event_cb function(obj, event)if event lvgl.EVENT_VALUE_CHANGED then local val (lvgl.slider_get_value(obj) or "0")..&…

在PHP8中遍历数组-PHP8知识详解

所谓遍历数组就是把数组中的变量值读取出来。遍历数组中的所有元素对程序员来说是经常使用的操作,通过遍历数组可以完成数组元素的查询工作。 这好比你去商场买东西一样,要买什么东西,就去该区域浏览一遍,以便找出适合自己的产品…

【JavaEE】_CSS常用属性值

目录 1. 字体属性 1.1 设置字体家族 font-family 1.2 设置字体大小 font-size 1.3 设置字体粗细 font-weight 1.4 设置字体倾斜 font-style 2. 文本属性 2.1 设置文本颜色 color 2.2 文本对齐 text-align 2.3 文本装饰 text-decoration 2.4 文本缩进 text-indent 2.…

合宙Air724UG LuatOS-Air LVGL API控件-图片 (Image)

图片 (Image) 图片IMG是用于显示图像的基本对象类型,图像来源可以是文件,或者定义的符号。 示例代码 -- 创建图片控件 img lvgl.img_create(lvgl.scr_act(), nil) -- 设置图片显示的图像 lvgl.img_set_src(img, "/lua/luatos.png") -- 图片…

【Linux】进程概念I --操作系统概念与冯诺依曼体系结构

Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法…感兴趣就关注我吧!你定不会失望。 本篇导航 1. 冯诺依曼体系结构为什么这样设计? 2. 操作系统概念为什么我们需要操作系统呢?操作系统怎么进行管理? 计算机是由两部分组…

性能监控-grafana+prometheus+node_exporter

Prometheus是一个开源的系统监控和报警工具。它由SoundCloud开发并于2012年发布,后来成为了一个独立的开源项目,并得到了广泛的应用和支持。 Prometheus的主要功能包括采集和存储各种系统和应用程序的监控数据,并提供强大的查询语言PromQL来…

算法:数组中的最大差值---“打擂台法“

文章来源: https://blog.csdn.net/weixin_45630258/article/details/132737088 欢迎各位大佬指点、三连 1、题目: 给定一个整数数组 nums,找出给定数组中两个数字之间的最大差值。要求,第二个数字必须大于第一个数字。 2、分析特…

【数据结构】搜索树MapSet

目录 1.搜索树 1.1概念 1.2查找 1.3插入 1.4删除 2.Map 2.1map说明 2.2TreeMap和HashMap 2.3常用方法 3.Set 3.1set说明 3.2TreeSet和HashSet 3.3常用方法 1.搜索树 1.1概念 二叉搜索树又称二叉排序树,它或者是一棵空树,或者具有以下性质&…

静态工厂模式,抽象工厂模式,建造者模式

静态工厂模式 ublic class FruitFactory {public static Fruit getFruit(String name) {Fruit fnull;switch (name){case "APPLE":{fnew Apple();}case "BANANA":{fnew Banana();}default :{System.out.println("Unknown Fruit");}}return f;} …

机器学习算法系列————决策树(二)

1.什么是决策树 用于解决分类问题的一种算法。 左边是属性,右边是标签。 属性选择时用什么度量,分别是信息熵和基尼系数。 这里能够做出来特征的区分。 下图为基尼系数为例进行计算。 下面两张图是对婚姻和年收入的详细计算过程(为GINI系…