网络编程
位置:首页>> 网络编程>> Python编程>> pytest-fixture简介及其用法讲解

pytest-fixture简介及其用法讲解

作者:爱吃水饺的小京  发布时间:2023-02-13 19:27:25 

标签:pytest,fixture,用法

什么是fixture

在一个测试过程中,fixture主要提供以下功能:

为测试提供上下文,比如环境变量,数据集(dataset),提供数据,数据和测试用例分开定义测试的步骤,主要用于setup和teardown
pytest中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集、配置测试前系统的初始状态、为批量测试提供数据源 fixture定义

使用装饰器 @pytest.fixture就表明这个函数是一个fixture
一个完整的fixture,定义如下:
@pytest.fixture(scope, params, autouse, ids, name)

如何使用fixture

最基本的用法就是一个fixture作为一个测试用例的参数传入,然后就可以在该测试用例中使用该fixture
当pytest执行一个测试用例时,就会检查参数,然后搜索是否有相同名字的fixture,如果有,就先执行这个fixture,得到fixture的返回值,然后将这个返回值作为参数传入到测试用例中

一个简单的fixture使用

import pytest

class Fruit():
   def __init__(self,name):
       self.name=name
       self.cubed=False

def cube(self):
       self.cubed=True

class FruitSalad():
   def __init__(self,*fruit_bowl):
       self.fruit=fruit_bowl
       self._cube_fruit()

def _cube_fruit(self):
       for fruit in self.fruit:
           fruit.cube()
@pytest.fixture()
def fruit_bowl():
   return [Fruit("apple"),Fruit("banana")]

def test_fruit_salad(fruit_bowl):
   fruit_salad=FruitSalad(*fruit_bowl)
   assert all(fruit.cubed for fruit in fruit_salad.fruit)

如果不使用fixture功能,代码需要这样写,这样就无法使用pytest来执行测试用例了

class Fruit():
   def __init__(self,name):
       self.name=name
       self.cubed=False

def cube(self):
       self.cubed=True

class FruitSalad():
   def __init__(self,*fruit_bowl):
       self.fruit=fruit_bowl
       self._cube_fruit()

def _cube_fruit(self):
       for fruit in self.fruit:
           fruit.cube()

def fruit_bowl():
   return [Fruit("apple"),Fruit("banana")]

def test_fruit_salad(fruit_bowl):
   fruit_salad=FruitSalad(*fruit_bowl)
   assert all(fruit.cubed for fruit in fruit_salad.fruit)

bowl = fruit_bowl()
test_fruit_salad(fruit_bowl=bowl)

使用fixture传递测试数据

fixture非常适合存放测试数据,并且它可以返回任何数据

import pytest

@pytest.fixture()
def a_tuple():
   return (1,'foo',None,{'bar':23})

def test_a_tuple(a_tuple):

assert a_tuple[3]["bar"]==32

a_tuple作为一个fixture,主要是提供测试数据给test_a_tuple,执行test_a_tuple时,先查看函数的参数,有a_tuple,并且找到了这个函数,先执行a_tuple,得到数据(1,‘foo’,None,{‘bar’:23}),并将这个数据传入到测试用例test_a_tuple中,在测试用例中,就可以直接使用a_tuple来使用这个测试数据

使用fixture来执行配置和销毁逻辑

fixture的另一个功能就是结合yield来配置测试用例的setup和teardown逻辑

import pytest

@pytest.fixture()
def task_db():
   print("start to setup....")
   yield "a"
   print("start to teardown...")

def test_db(task_db):
   print(task_db)
   print("start to test")

运行结果:

start to setup....
a
start to test
start to teardown..

fixture函数会在测试函数之前运行,但如果fixture函数包含yield,那么系统会在yield处停止,转而运行测试函数,等测试函数执行完毕后再回到fixture,继续执行yield后面的代码,因此,可以将yield之前的代码视为配置过程(setup),将yield之后的代码视为清理过程(teardown),无论测试过程中发生了什么,yield之后的代码都会执行,yield可以返回值,也可以不返回

fixture可以使用其他的fixture

import pytest
@pytest.fixture()
def first_entry():
   return "a"

@pytest.fixture()
def order(first_entry):
   return [first_entry]

def test_order(order):
   order.append("b")
   assert order==["a","b"]

同时使用多个fixture

一个测试用例或者一个fixture可以同时使用多个fixture

import pytest

@pytest.fixture()
def first_entry():
   return "a"
@pytest.fixture()
def second_entry():
   return 2

@pytest.fixture()
def order(first_entry,second_entry):
   return [first_entry,second_entry]

@pytest.fixture()
def expect_list():
   return ["a",2,3.0]

def test_order(order,expect_list):
   order.append(3.0)
   assert order==expect_list

fixture的参数介绍

scope,指定fixture的作用范围

用于控制fixture执行的配置和销毁逻辑的频率
scope参数有四个值:function,class,module,session
默认值为function
function:函数级别的fixture每个测试函数只需要运行一次,
class:类级别的fixture每个测试类只运行一次
module:模块级别的fixture,每个模块只需要运行一次
session:绘画级别的fixture,每次会话只需要运行一次

params,fixture的参化

params是一个list,这个list是要传入fixture的参数,会引起多次调用,request.param可以获取每一个值

import pytest
@pytest.fixture(params=["a","b"])
def order(request):
   return request.param
def test_order(order):
   all_order="ab"
   assert order in all_order

运行结果:

collected 2 items                                                                                                                                                                                                         

test_usefixture7.py::test_order[a] PASSED
test_usefixture7.py::test_order[b] PASSED

request是python的一个内置的fixture,代表fixture的调用状态,它有一个param字段,会被@pytest.fixture(params=[“a”,“b”])的params列表中的一个元素填充,如果params有多个值,就会多次调用requeat.param来多次执行测试用例

autouse,为常用的fixture添加autouse选项

对于常用的fixture,可以指定autouse=True,使作用域内的测试函数都自动运行该fixture

name,为fixture重命名

import pytest

@pytest.fixture(name="lue")
def a_b_c_d_e():
   return "a"
def test_order(lue):
   assert lue=="a"

import pytest

@pytest.fixture(name="lue")
def a_b_c_d_e():
   return "a"
def test_order(lue):
   assert lue=="a"

PS:

下面来说下pytest中的fixture参数解析以及用法

当我们在使用pytest实现前后置调用时有两种方式

方式一:

        采用setup/teardown以及setup_class/teardown_class类似这种方式去实现前后置调用

方式二:

        采用pytest中强大的fixture装饰器来实现

本期文章主要采用方式二来解决测试用例前后置调用的问题

首先我们来看下,pytest中的fixture的参数有哪些,分别是scope,params,autouse,ids,name这5个形参,哪些他们分别的作用域以及作用是什么呢? 

下面来说下scope:

“”“
scope:
   function(默认)
   class
   module
   session
params:
   参数化,支持list,tuple,字典列表,字典元组
autouse:
   false(默认)
   True
ids:
   当使用params参数化时,给每一个值设置一个变量名,其实意义不大
name:
   表示的是被@pytest.fixture标记的方法取一个别名,注意:当去了别名之后,原来的名称无法使用
”“”
@pytest.fixture(scope='function')
def my_fixture():
   print('这是前置内容')
   yield
   print('这是后置内容')

class Testdemo():

def test01(self,my_fixture):
       print('这是test01')

def test02(self):
       print('这是test02')

根据上面的结构,运行后输出的内容为
这是前置内容
这是test01
这是后置内容
这是前置内容
这是test02
这是后置内容

对于上述方法中传入my_fixture的做法,主要是对比setup/teardown之类的更方便,不需要每个方法都在运行之前执行一边setup,而是在某个方法需要这种操作时在执行

来源:https://blog.csdn.net/ljsykf/article/details/128315139

0
投稿

猜你喜欢

  • 今天新能测试组的同事找我看一个奇怪的现象。一个tomcat应用,里面只有一个单纯的jsp页面,而且这个jsp页面没有任何java代码(想用这
  • 字符串索引示意图字符串切片也就是截取字符串,取子串Python中字符串切片方法字符串[开始索引:结束索引:步长]切取字符串为开始索引到结束索
  • 在oracle中有很多关于日期的函数,如:1、add_months()用于从一个日期值增加或减少一些月份date_value:=add_mo
  • 做教育业的网站,会将此遇到这个问题:如何在网页上显示音标?音标为什么显示为乱字符?等等类似的问题。前两天做沪江网某英语页面的时候也碰到了这个
  • 一、使用装饰器实现单例def Singleton(cls):    _instance = {}  
  • 在最近一次项目有一个需求,点击按钮——异步提交——异步响应返回——根据响应返回值新开窗口。这有两个要点:异步响应之前不知道要打开窗口的URL
  • 1、除法相关在python3之前,print 13/4  #result=3然而在这之后,却变了!print(13 / 4) #r
  • 目录1.技术背景2.问题复现3.解决思路4.总结概要1.技术背景笔者在执行一个Jax的任务中,又发现了一个奇怪的问题,就是明明只分配了很小的
  • 我认为在ASP中最好的办法是用编程实现定时刷新Cache,也就是说给Application中储存的设一个过期时间。当然,在ASP中Appli
  • 小的本身是一个平面设计人员,前一阵儿有一些空闲的时间,便在各个站长网上发布了贴子,大意是免费制作logo,以换取网站连接(相信很多人都看过)
  • 1. PHP入侵检测系统PHP IDS(即PHP-入侵检测系统)是一套易于使用、结构良好、速度出色且专门面向PHP类Web应用程序的先进安全
  • 很高兴参加了这一期的薯片会,认识了几个朋友~~不料的却是今天我要来总结一下本次薯片会我们总共讨论了三个议题:A、 如何让“用户”更容易识别超
  • 在做项目的过程中,我们经常会建立各种各样的规范,以方便团队之间更好的合作更好的完成项目;同样我们也经常会听到各种各样的协议,比如Google
  • 在分析sIFR之前,先来快速的了解一下sIFR是什么,以及它是如何工作的。sIFR表示scalable Inman Flash Replac
  • 自己写了一个简单的python脚本,用来推送zabbix告警到钉钉机器人,推送格式为markdown,有需要的可以自己修改markdown的
  • 应用场景1.需要将大型MP3文件切割成较小的部分以便上传或发送。2.需要从MP3文件中提取特定的音频片段,以便用于其他目的。3.需要快速制作
  • SQL Server 2005的新功能为动态管理对象,它们是在指定时间返回某个数据库实例的特殊状态信息的数据库视图或函数。这些对象允许数据库
  • delete 删除一张大表时空间不释放,非常慢是因为占用大量的系统资源,支持回退操作,空间还被这张表占用着。truncate table 表
  • 1.H5 download属性function downFile(content, filename) {  // 创建隐藏的可下
  • 首先在我们进行信息系统的开发的时候,数据库的应用必不可少,对于一个企业级别的数据库应用很少是只使用一块磁盘的,很多都是使用RAID磁盘阵列,
手机版 网络编程 asp之家 www.aspxhome.com