什么是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. 【Linux】【Services】【Package】rpm

    CentOS系统上rpm命令管理程序包:         安装.升级.卸载.查询和校验.数据库维护                   rpm命令:rpm  [OPTIONS]  [PACKAGE_F ...

  2. 智龙开发板搭建llsp环境

    智龙开发板搭建llsp(linux+lighttpd+sqlite3+php)环境 1. 准备 1. 智龙开发板V3 2. 软件编译环境:VirtualBox6+CentOS6.10-i386.min ...

  3. Mysql配置 主从同步

    目录 一.准备 二.操作 主数据库操作 从服务器操作 一.准备 1.主从数据库版本最好一致 2.主从数据库内数据保持一致,若不一致,可将从库中所有数据删除,并将主库全部数据导入进去 主数据库:182. ...

  4. windows下python3.7安装gmpy2、Crypto 库及rsa

    基于python3.7在windows下安装gmpy2 先检查一下是否安装了wheel文件包,在cmd中输入wheel,查看一下,如果没有安装,则输入安装:pip install wheel 如果遇到 ...

  5. 新建任务(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 新建任务,这操作简单得就跟在Excel的单元格里输入个数据一样,不过也不是一点讲究都没有. 首先得选对视图. 不是所有的视 ...

  6. Arcpy按属性(字段值)不同将shp分割为多个独立shp_适用点线面矢量

    利用代码可以进行批量处理,安装有10.5及以上版本ArcGIS可以使用工具Split by attributes完成上述任务 # -*- coding: utf-8 -*- # Import syst ...

  7. LuoguP7398 [COCI2020-2021#5] Šifra 题解

    Content 给定一个长度 \(n\) 的只包含小写字母和 \(0\sim9\) 的字符串(字符串中的字母可视为分隔符).求字符串中包含多少个不同的数字. 数据范围:\(1\leqslant n\l ...

  8. 我的邮箱客户端程序Popmail

    05年的时候写了一个邮箱客户端程序.当时主要目的是研究POP3和SMTP协议,同时锻炼自己的网络编程能力.当然了,如果自己写的邮箱客户端能够满足自身的日常工作需要,而不是频繁的登录不同的网页邮箱,那就 ...

  9. ACwing1208. 翻硬币

    题目: 小明正在玩一个"翻硬币"的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:**oo***oooo 如果 ...

  10. JAVA删除某个文件夹(递归删除文件夹的所有文件)

    /** * 递归删除文件夹下所有内容 最后删除该文件夹 * @param filePath 要删除的文件夹路径 * @return */ public boolean deleteFiles(Stri ...