什么是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. SpringBoot中使用JUnit4(入门篇)

    添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...

  2. MFC入门示例之列表框(CListControl)

    初始化: 1 //初始化列表 2 m_list.ModifyStyle(LVS_TYPEMASK, LVS_REPORT); //报表样式 3 m_list.InsertColumn(0, TEXT( ...

  3. 安全刻不容缓「GitHub 热点速览 v.21.50」

    作者:HelloGitHub-小鱼干 本周最热的事件莫过于 Log4j 漏洞,攻击者仅需向目标输入一段代码,不需要用户执行任何多余操作即可触发该漏洞,使攻击者可以远程控制用户受害者服务器,90% 以上 ...

  4. 微软开源的Web测试和自动化神器 Playwright

    Playwright 是微软开源的一个用于 Web 测试和自动化的框架, 提供了可靠的端到端测试, 功能非常强大, 可以在测试, 爬虫,自动化场景中使用. 跨浏览器 Playwright 支持所有现代 ...

  5. Mysql实例 表设计

    目录 一.介绍 二.设计表格 三.查询 查都有哪些公司 查A公司都放了哪些广告 查A公司10月份该交多少广告费 四.分析 表结构设置 sql语句 其它功能 一.介绍 有一个公司叫月亮集团,他们旗下有很 ...

  6. 漫谈IRP

    I/O Request Packet(IRP) IRP概述: IRP是由I/O管理器发出的,I/O管理器是用户态与内核态之间的桥梁,当用户态进程发出I/O请求时,I/O管理器就捕获这些请求,将其转换为 ...

  7. 项目管理的基本概念(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 关于项目管理的基本概念,我看了好久,也迷糊了好久--原谅我实在不是个善于理解概念的妖,最终我决定,就记些简单的东东吧,具体 ...

  8. java 输入输出IO 转换流-字符编码

    编码和其产生的问题: 计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字.英文.标点符号.汉字等字符是二进制数转换之后的结果. 按照某种规则,将字符存储到计算机中,称为编码 .反之,将存 ...

  9. mysql表死锁查询

    1.查询是否锁表show open tables where in_use>0; 2.查询进程show processlist查询到相对应的进程,然后 kill id 3.查看正在锁的事务sel ...

  10. birt分组时,如何让居中

    birt分组时,如何让居中,如下图,选择cell格,然后调整属性为all,如下图所示,