1、fixture简绍

官方解释如下

Decorator to mark a fixture factory function.
This decorator can be used, with or without parameters, to define a fixture function.
The name of the fixture function can later be referenced to cause its invocation ahead of running tests: test modules or classes can use the pytest.mark.usefixtures(fixturename) marker.
Test functions can directly use fixture names as input arguments in which case the fixture instance returned from the fixture function will be injected.
Fixtures can provide their values to test functions using return or yield statements. When using yield the code block after the yield statement is executed as teardown code regardless of the test outcome, and must yield exactly once.

https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest.fixture
fixture属于pytest中的一个方法。fixture可以用作测试用例的前置和后置操作,其中fixture命令规范没有像setup和teardown固定格式。可以随意命名。控制fixture的前置和后置操作是通过yield关键字进行来区分的,代码在yield前面的属于前置操作,代码在yield后面的属于后置操作。并且fixture也没有强烈的要求必须要前后置同时存在,可以只存在前置也可以只存在后置。
fixture如果有后置内容,无论遇到什么问题,都会进行执行后置的代码。

2、fixture基本用法

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture
def login():print("login:用户执行登录操作")# 使用夹具函数的测试用例
def test_01(login):print("test_01")# 使用夹具函数的测试用例
def test_02(login):print("test_02")# 不使用夹具函数的测试用例
def test_03():print("test_03")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

执行结果:

collected 3 itemsMyPytest.py login:用户执行登录操作
test_01
.login:用户执行登录操作
test_02
.test_03
.
============================== 3 passed in 0.07s ==============================

fixture通过@pytest.fixture()装饰器装饰login()函数,那么这个函数就是一个fixture。
上述代码中,声明的测试夹具函数login,作为参数传入其他函数(不需要带括号哦),即可完成调用。可以传多个fixture,按先后顺序执行。

3、调用fixture的方式

a、Fixture名字作为测试用例的参数

即上述案例中的调用方式,将定义的fixture作为测试用例的参数传递进去:

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture
def login():print("login:用户执行登录操作")# 使用夹具函数的测试用例
def test_01(login):print("test_01")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

b、使用@pytest.mark.usefixtures(‘fixture’)装饰器

使用@pytest.mark.usefixtures('fixture')的方式调用,效果同上:

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture
def login():print("login:用户执行登录操作")# 使用夹具函数的测试用例
@pytest.mark.usefixtures('login')
def test_01():print("test_01")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

c、使用autouse参数

@pytest.fixture()的参数中的字段autouse = True的情况下,默认会在模块内的每条用例调用时候自动用到:

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture(autouse=True)
def login():print("login:用户执行登录操作")# 自动使用夹具函数的测试用例
def test_01():print("test_01")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

4、fixture函数参数

![image.png](https://img-blog.csdnimg.cn/img_convert/bd9f4733e197a0674d82010189f1e792.png#clientId=u72bc370c-d735-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=412&id=u77733fa1&margin=[object Object]&name=image.png&originHeight=497&originWidth=944&originalType=binary&ratio=1&rotation=0&showTitle=false&size=77248&status=done&style=none&taskId=u5c1cbd35-b30f-421a-9e87-3efdc20372b&title=&width=782)

@pytest.fixture(scope = “function”,params=None,autouse=False,ids=None,name=None)

scope

控制fixture的作用范围,也就是哪些用例需要调用这个fixture。有点类似之前讲过的setup_module 、setup_class等等。

取值 作用
function 函数级 每一个函数或方法都会调用
class 函数级 模块级 每一个.py文件调用一次
module 模块级 每一个.py文件调用一次
session 会话级 每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法

session的讲解,我后面在conftest.py的用法时候讲解。
举个例子说明:

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture(scope="class")
def login():print("login:用户执行登录操作")# 当fixtrue的scope="class",则只在该类中执行一次
class Test_Fixture():def test_02(self, login):print("test_02")def test_03(self, login):print("test_03")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])
collected 2 itemsMyPytest.py login:用户执行登录操作
test_02
.test_03
.============================== 2 passed in 0.07s ==============================***Repl Closed***

params

Fixture的可选形参列表,支持列表传入,默认None,每个param的值,fixture都会去调用执行一次,类似for循环,可与参数ids一起使用,作为每个参数的标识,详见ids。被Fixture装饰的函数要调用是采用:request.param(固定写法)

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture(params=["胡八万","胡三条","胡七筒"])
def login(request):temp = request.paramprint(f"login:用户{temp}执行登录操作")return temp#当fixture 的params参数 会被循环执行
def test_01(login):print(f"{login}已经登录成功~")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])
collected 3 itemsMyPytest.py login:用户胡八万执行登录操作
胡八万已经登录成功~
.login:用户胡三条执行登录操作
胡三条已经登录成功~
.login:用户胡七筒执行登录操作
胡七筒已经登录成功~
.============================== 3 passed in 0.07s ==============================***Repl Closed***

ids

用例标识ID,与params配合使用,一对一关系

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture(params=["胡八万", "胡三条", "胡七筒"],ids=['用例A','用例B','用例C'])
def login(request):temp = request.paramprint(f"login:用户{temp}执行登录操作")return temp# 当fixture 的params参数 会被循环执行
def test_01(login):print(f"{login}已经登录成功~")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

有的编辑器执行无效果,但是使用pycharm等就可以看出用例的编号

autouse

默认False,若为True,刚每个测试函数都会自动调用该fixture,无需传入fixture函数名。参考之前的代码案例。

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture(autouse=True)
def login():print("login:用户执行登录操作")# 自动使用夹具函数的测试用例
def test_01():print("test_01")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

name

fixture的重命名。重新把他命名一下,之前的函数名将不生效

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture(name='new_login')
def login(request):print(f"login:用户执行登录操作")def test_01(new_login):print("test_01已经登录成功~")def test_02(login):print("test_02已经登录成功~")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

执行上述代码将报错,提示fixture 'login' not found

5、fixture对比setup、teardown

  • 全局共享conftest.py,可以统一管理、多处调用和自动调用
  • 命名方式灵活,不局限于setup和teardown这个几个命名
  • fixture出现重名,就近原则
  • conftest.py为fixture而生的,可以方便管理、修改和查看fixture函数
  • 自动引入不需要导入

6、fixture配合yield 实现teardown

关于yield可以看我之前写的一篇专门介绍它基本用法的文章。这里不再赘述
yeild也是一种函数的返回值类型,是函数上下文管理器,使用yield被调fixture函数执行遇到yield会停止执行,接着执行调用的函数,调用的函数执行完后会继续执行fixture函数yield关键后面的代码。因此利用fixture函数,我们可以说pytest集合了setup、teardown,既做了初始化,又做了后置的清理工作。

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture()
def login(request):print("login:用户执行登录操作")yieldprint("退出登录~")def test_01(login):print("test_01已经登录成功~")def test_02(login):print("test_02已经登录成功~")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

执行结果:

collected 2 itemsMyPytest.py login:用户执行登录操作
test_01已经登录成功~
.退出登录~
login:用户执行登录操作
test_02已经登录成功~
.退出登录~============================== 2 passed in 0.07s ==============================***Repl Closed***

7、addfinalizer 终结函数

addfinalizer,终结函数。效果上是大致相同的,但是在用法上,addfinalizer跟yield是不同的,需要注册作为终结器使用的函数。

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture()
def login(request):print("login:用户执行登录操作")def logout():print("退出登录~")# 注册logout为终结函数request.addfinalizer(logout)def test_01(login):print("test_01已经登录成功~")def test_02(login):print("test_02已经登录成功~")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

执行结果:

collected 2 itemsMyPytest.py login:用户执行登录操作
test_01已经登录成功~
.退出登录~
login:用户执行登录操作
test_02已经登录成功~
.退出登录~============================== 2 passed in 0.07s ==============================***Repl Closed***

addfinalizer可以定义多个终结函数,但是执行顺序是定义时候顺序的倒叙:

import pytest# 定义的夹具函数,使用装饰器pytest.fixture
@pytest.fixture()
def login(request):print("login:用户执行登录操作")def logout01():print("退出登录01~")def logout02():print("退出登录02~")def logout03():print("退出登录03~")# 注册logout为终结函数request.addfinalizer(logout01)request.addfinalizer(logout02)request.addfinalizer(logout03)def test_01(login):print("test_01已经登录成功~")def test_02(login):print("test_02已经登录成功~")if __name__ == '__main__':pytest.main(['MyPytest.py', '-s'])

运行结果:

collected 2 itemsMyPytest.py login:用户执行登录操作
test_01已经登录成功~
.退出登录03~
退出登录02~
退出登录01~
login:用户执行登录操作
test_02已经登录成功~
.退出登录03~
退出登录02~
退出登录01~============================== 2 passed in 0.07s ==============================***Repl Closed***

好了,今天的内容比较多,因为pytest的精髓也在fixture。所以希望本文的案例大家跟着大家敲一遍,纸上得来终觉浅~

对你有用的话点个赞吧!

pytest系列教程——4、fixture详解相关推荐

  1. h2 不能访问localhost_SpringBoot2.x系列教程44--H2数据库详解及搭建Web控制台

    SpringBoot2.x系列教程44--H2数据库详解及搭建Web控制台 作者:一一哥 我在上一章节中讲解了Spring Boot中整合Mybatis,接下来我给大家介绍一款内存数据库--H2. H ...

  2. Redis系列教程(二):详解Redis的存储类型、集群架构、以及应用场景

    高并发架构系列 高并发架构系列:数据库主从同步的3种一致性方案实现,及优劣比较 高并发架构系列:Spring Cloud的核心成员.以及架构实现详细介绍 高并发架构系列:服务注册与发现的实现原理.及实 ...

  3. Cobaltstrike系列教程(三)beacon详解

    0x000–前文 有技术交流或渗透测试培训需求的朋友欢迎联系QQ/VX-547006660 2000人网络安全交流群,欢迎大佬们来玩 群号820783253 0x001-Beacon详解 1.Beac ...

  4. 一步一步使用ABP框架搭建正式项目系列教程之本地化详解

    返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 本篇目录 扯扯本地化 ABP中的本地化 小结 扯扯本地化 本节来说说本地化,也有叫国际化.全球化的,不管怎么个叫法,反正道理都是一 ...

  5. python fixture_python pytest进阶之xunit fixture详解

    前言 今天我们再说一下pytest框架和unittest框架相同的fixture的使用, 了解unittest的同学应该知道我们在初始化环境和销毁工作时,unittest使用的是setUp,tearD ...

  6. junit5 入门系列教程-02-junit5 注解详解

    目录 目录 Junit5 注解 @Test @ParameterizedTest @RepeatedTest @TestFactory @TestInstance @TestTemplate @Dis ...

  7. 『SQLServer系列教程』——事务详解

  8. RxJS 系列之二 - Observable 详解

    查看新版教程,请访问前端修仙之路 RxJS 系列目录 RxJS 系列之一 - Functional Programming 简介 RxJS 系列之二 - Observable 详解 (本文) RxJS ...

  9. jquery系列教程3-DOM操作全解

    全栈工程师开发手册 (作者:栾鹏) 快捷链接: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件 ...

  10. python语言入门详解-python初级教程:入门详解

    python初级教程:入门详解 Crifan Li 目录 前言 .................................................................... ...

最新文章

  1. 文件服务器搭建 xp,xp文件服务器搭建
  2. 永远不要去依赖别人_读书心得马琴:永远不要依靠别人来保证你的安全读后感...
  3. 博科b8网络版定位服务器位置,如何在企业服务器中采集奥维GPS定位设备的位置...
  4. 小米kali linux蓝牙,小米筆記本在Kali Linux下所遇問題部分解決方案(持續更新中)...
  5. 方立勋_30天掌握JavaWeb_Session
  6. android搭建https,android 搭建https Server(示例代码)
  7. [译]试用新的System.Text.Json API
  8. python pp模块_python常用模块
  9. VMware和NVIDIA推出新一代混合云架构
  10. python决策树逻辑回归_百面机器学习(逻辑回归以及决策树,leetcode)
  11. [转]用了docker是否还有必要使用openstack?
  12. Jmeter(五)录制功能
  13. Linux top命令里面%CPU和cpu(s)的差别
  14. MySQL数据库的基础操作
  15. 20X01 FCPX插件 音频可视化视觉特效 PFS Fcpx Audio Effector
  16. js框架jquery实现的幸运大转盘抽奖程序代码,兼容多种浏览器(Internet Explorer 6.0+ 、Firefox 2.0 、Safari 3 、Opera 9 、Chrome)
  17. pg安装部署linux_Linux下postgresql数据库部署与配置
  18. 【软考】PV操作同步互斥
  19. java实现excel导入导出,对象图片读取,上传七牛云
  20. Python学习第八节

热门文章

  1. ArrayList源码分析--底层扩容机制
  2. 新手必备的矢量网络分析仪使用教程
  3. B站视频缓存 音频和视频批量合并
  4. 罗马数字转换器|罗马数字生成器
  5. android 小米键盘输入法切换,小米输入法键盘设置
  6. 新浪微博PC端登录分析
  7. 新路由3详细刷机教程
  8. 网络安全笔记-网络设备专场(路由器、交换机、防火墙)
  9. Excel2013使用插入特殊符号或复选框功能制作带对号的打钩方框
  10. Unity中的资源管理-资源类型和基本使用