什么是fixture

fixture是pytest特有的功能,使用装饰器 @pytest.fixture 标记的函数在其他函数中能被当作参数传入并被调用。

fixture有明确的名字,在其他函数,模块,类或整个工程调用它时会被激活。

fixture是基于模块来执行的,每个fixture的名字就可以触发一个fixture的函数,它自身也可以调用其他的fixture。

fixture作用是为了提供一种可靠和可重复的手段去运行那些最基本的测试内容。比如在测试网站的功能时,每个测试用例都要登录和退出,利用fixture就可以只做一次,否则每个测试用例都要做这两步就显得很冗余。

fixture的参数

fixture的可用参数如下:

  • scope:定义被fixture装饰方法的作用域。可用参数值如下:

    • function(默认):作用域为每个函数或方法
    • class:作用域为每个类。
    • module:作用域为每个模块(每个py文件)。
    • session:作用域为每次启动。
  • autouse=True:自动执行被fixture装饰的方法。默认为False
  • params:用于参数化,数据类型支持列表和元组。(比如:params=[“v1”, "v2", "v3"])
  • ids:当使用params参数化时,将nodeid中的变量值替换为给定的值(很少使用)
  • name:给被fixture标记的方法取别名。(很少使用,注:当取了别名后,原方法名就不可以用了)

scope参数完成前后置操作

function:作用于每个函数(与setup和teardown功能相似)

import pytest

# function作用范围为每个函数或方法
@pytest.fixture(scope="function")
def my_fixture():
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield
print("\n后置操作") class TestPractice1: # 因为没使用autouse参数,使用时需要传入方法名
def test_001(self, my_fixture):
print("执行用例001") def test_002(self):
print("执行用例002") class TestPractice2: def test_003(self, my_fixture):
print("执行用例003") def test_004(self):
print("执行用例004")

执行结果

class:作用于每个类(与setup_class和teardown_class功能相似)

import pytest

# class作用范围为每个类
@pytest.fixture(scope="class")
def my_fixture():
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield
print("\n后置操作") class TestPractice1: # 因为没使用autouse参数,使用时需要传入方法名
def test_001(self, my_fixture):
print("执行用例001") def test_002(self):
print("执行用例002") class TestPractice2: def test_003(self):
print("执行用例003") def test_004(self, my_fixture):
print("执行用例004")

执行结果

module:作用于每个模块

import pytest

# module作用范围为每个模块
@pytest.fixture(scope="module")
def my_fixture():
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield
print("\n后置操作") class TestPractice1: # 因为没使用autouse参数,使用时需要传入方法名
def test_001(self, my_fixture):
print("执行用例001") def test_002(self):
print("执行用例002") class TestPractice2: def test_003(self):
print("执行用例003") def test_004(self, my_fixture):
print("执行用例004")

执行结果

session:作用于每次启动

autouse参数值为True时,被fixture装饰的函数自动被调用

上面我们使用被fixture装饰的函数,都需要将其函数名称当作参数传入到要使用的方法中。需要注意,自动执行范围与scope的作用域相关。

import pytest

@pytest.fixture(autouse=True)
def my_fixture():
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield
print("\n后置操作") class TestPractice1: # 因为没使用autouse参数,使用时需要传入方法名
def test_001(self):
print("执行用例001") def test_002(self):
print("执行用例002") class TestPractice2: def test_003(self):
print("执行用例003") def test_004(self):
print("执行用例004")

执行结果

params用于参数化,数据类型支持列表和元组。

在上面的例子中,fixture返回值都是None,我们可以选择让fixture返回我们需要的东西。如果你的fixture需要配置一些数据,读个文件,或者连接一个数据库,那么你可以让fixture返回这些数据或资源。

实现步骤:

  1. 在fixture中使用params参数;
  2. 在被fixture装饰的函数中添加request,request是固定写法;
  3. 使用 yield 或 return 返回 request.param request.param是固定写法;
  4. 在要使用的方法中,添加被fixture装饰的函数名;

注意:参数化时,如果使用了autouse,每个方法都会执行一次参数化,所以autouse慎用。

import pytest

@pytest.fixture(params=[1, 2, 3])
def my_fixture(request):
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield request.param
print("\n后置操作") class TestPractice1: # 参数化
def test_001(self, my_fixture):
print("执行用例001")
print(f"获取参数化的值:{my_fixture}") def test_002(self):
print("执行用例002")

执行结果

如果没有前后置操作,只想做参数化操作,我们可以使用return返回 request.param

import pytest

@pytest.fixture(params=[1, 2, 3])
def my_fixture(request):
return request.param class TestPractice1: # 参数化
def test_001(self, my_fixture):
print("执行用例001")
print(f"获取参数化的值:{my_fixture}") def test_002(self):
print("执行用例002")

执行结果

ids用于在参数化时,将nodeid中的变量值替换为给定的值

import pytest

@pytest.fixture(params=[1, 2, 3], ids=["v1", "v2", "v3"])
def my_fixture(request):
# yield之前为前置操作,yield之后为后置操作
return request.param class TestPractice1: # 参数化
def test_001(self, my_fixture):
print("执行用例001")
print(f"获取参数化的值:{my_fixture}") def test_002(self):
print("执行用例002")

执行结果

name用于给被fixture标记的方法取别名

name用于给被fixture标记的方法取别名

import pytest

@pytest.fixture(name="rename_fixture")
def my_fixture(request):
print("前置操作")
yield
print("后置操作") class TestPractice1: # 使用方法别名调用fixture
def test_001(self, rename_fixture):
print("执行用例001") def test_002(self):
print("执行用例002")

需要注意是,使用该参数后,原函数名就不可用了。

fixture可以互相调用

import pytest

@pytest.fixture()
def fixture_1():
print("\nfixture1的前置")
yield
print("fixture1的后置") # 在fixture_2中调用fixture_1
@pytest.fixture()
def fixture_2(fixture_1):
print("fixture2的前置")
yield
print("\nfixture2的后置") class TestPractice1: # 调用fixture_2
def test_001(self, fixture_2):
print("执行用例001") def test_002(self):
print("执行用例002")

执行结果

一个用例可以调用多个fixture

import pytest

@pytest.fixture()
def fixture_1():
print("fixture1的前置")
yield
print("\nfixture1的后置") @pytest.fixture()
def fixture_2():
print("\nfixture2的前置")
yield
print("fixture2的后置") class TestPractice1: # 调用多个fixture,执行顺序与调用顺序有关
def test_001(self, fixture_2, fixture_1):
print("执行用例001") def test_002(self):
print("执行用例002")

执行结果

conftest.py和@pytest.fixture结合使用设置全局可用

上面的演示,用例和fixture均是在同一个文件中,我们可以创建一个固定名称为conftest.py的文件,将其放在用例同级或上级以上目录,在这个文件中定义一个被fixture装饰的函数,这个函数可以在其下级任意目录,不需要import而直接使用。

这里有以下几点需要注意:

  1. 文件名称固定为conftest.py
  2. 在conftest.py定义的fixture函数不需要import就可以直接使用
  3. conftest.py影响的作用域为同级及其所有子目录
  4. conftest.py文件可以创建多个,当多个文件存在相同的fixture函数名是,最近的作用域函数功能生效

Pytest_fixture(9)的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  3. ASP.NET Core 之 Identity 入门(一)

    前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...

  4. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  5. Online Judge(OJ)搭建(第一版)

    搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...

  6. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  7. 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成

    阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...

  8. 【.net 深呼吸】细说CodeDom(5):类型成员

    前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...

  9. 【.net 深呼吸】细说CodeDom(4):类型定义

    上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...

随机推荐

  1. 一文读懂RESTful架构

    转载自https://zhuanlan.zhihu.com/p/381554129 RESTful架构究竟是什么 别着急,想要了解RESTful,我们先来了解一位大佬Roy Thomas Fieldi ...

  2. contrller层的编码设设计流程以及详细配置

    /**      实际开发中遵循一个规律:自己写的类使用注解,系统提供的类使用配置文件 1.书写controller类----->配置springmvc.xml-------->配置web ...

  3. java 整型

    byte(1字节).short(2字节).int(4字节).long(16字节) java中前缀加上0b或者0B就可以写二进制数,前缀加上0就可以写八进制数,前缀加上0x或者0X就可以写十六进制数 一 ...

  4. Laravel框架角色、权限

    角色表结构如下: 权限表结构如下: 控制器代码: //递归查询权限列表 public function index(){ $data = ManagePermissionModel::query()- ...

  5. vs2019+windows服务+nancy+打包

    一.创建windows服务  二.nuget包添加nancy 1.nancy 2.0.0和Nancy.Hosting.Self 2.0.0插件 2.项目添加文件夹Modules,在Modules文件夹 ...

  6. 【CF1591】【数组数组】【逆序对】#759(div2)D. Yet Another Sorting Problem

    题目:Problem - D - Codeforces 题解 此题是给数组排序的题,操作是选取任意三个数,然后交换他们,确保他们的位置会发生改变. 可以交换无限次,最终可以形成一个不下降序列就输出&q ...

  7. Offset函数(Excel函数集团)

    此处文章均为本妖原创,供下载.学习.探讨! 文章下载源是Office365国内版1Driver,如有链接问题请联系我. 请勿用于商业!谢谢 下载地址:https://officecommunity-m ...

  8. CF753A Santa Claus and Candies 题解

    Content 圣诞老人有 \(n\) 颗糖果,他想把这些糖果分发给一些小孩子,并想要每个孩子都能得到不同的糖果数目.求能得到糖果的孩子的最大数目,以及他们各自得到的糖果数. 数据范围:\(1\leq ...

  9. CF977B Two-gram 题解

    Content 给定一个字符串 \(s\),请求出出现次数最多的长度为 \(2\) 的子串. 数据范围:\(2\leqslant |s|\leqslant 100\). Solution 直接求出所有 ...

  10. LuoguP7426 [THUPC2017] 体育成绩统计 题解

    Update \(\texttt{2021.3.11}\) 修复了一个笔误. Content 太长了,请直接跳转回题面查看. 数据范围:\(n\leqslant 10^4\),\(0\leqslant ...