pytest-fixtured自动化测试详解

fixture的作用

1.同unittest的setup和teardown,作为测试前后的初始化设置。

fixture的使用

1.作为前置条件使用

2.fixture的的作用范围

1.作为前置条件使用

@pytest.fixture()
def a():
    return 3
 
def test_b(a):
    assert a==3

2.fixture的作用范围
首先实例化更高范围的fixture.默认为scope="function",每个测试函数都会执行一次。

session : 多个.py文件执行时,只调用一次
module: 每一个.py调用一次
class : 每个类调用一次
function: 每个函数调用一次
3.fixture 作为setup/teardown执行
yield 前的在测试之前执行,yield后的在测试完后执行

@pytest.fixture
def a():
    print("setup")
    yield
    print("teardown")
 
def test_b(a):
    print("测试")

4.fixture with

# @pytest.fixture()
# def write_file():
#     f = open("myfile.txt","w")
#     f.write("hello")
#     yield
#     f.close()
@pytest.fixture()
def write_file():
    with open("myfile.txt","w") as f:
        f.write("hello1")
 
def test_write_file(write_file):
    print("ceshi")

5. fixture request可以请求测试的上下文

@pytest.fixture(params=[1,3])
def a(request):
    return request.param
 
def test_b(a):
    assert a in [1,3]

6.fixture 工厂模式

在单个测试中,如果想多次调用该fixture,就可以用工厂模式。fixture的结果返回的不是数据,而是返回生成数据的函数。

@pytest.fixture
def make_customer_record():
    def _make_customer_record(name):
        return {"name": name, "orders": []}
 
    return _make_customer_record
 
 
def test_customer_records(make_customer_record):
    customer_1 = make_customer_record("Lisa")
    customer_2 = make_customer_record("Mike")
    customer_3 = make_customer_record("Meredith")

7.带参数的fixture

params列表有几个值,测试就会执行几次。例params=[1,2],测试用例会执行2次

@pytest.fixture(params=[0, 1, pytest.param(2, marks=pytest.mark.skip)])
def data_set(request):
    return request.param
 
 
def test_data(data_set):
    assert data_set in [0,1]

8. 模块化:在一个fixtrue调用另一个fixture

fixture a可以调用另一个fixture c

@pytest.fixture()
def c():
    print("c")
 
@pytest.fixture()
def a(c):
    print("a")
 
def test_b(a):
    pass

9.通过fixture 对测试用例进行分组
pytest在测试运行期间最大程度地减少了fixture的数量。如果有参数化的fixtrue,那么使用它的所有测试将首先使用一个实例执行,然后在创建下一个fixture实例之前调用终结器。除其他外,这简化了对创建和使用全局状态的应用程序的测试。

@pytest.fixture(scope="module", params=[1, 2])
def input_x(request):
    print("setup")
    param = request.param
    yield param
    print("teardown")
 
def test_a(input_x):
    print("test_a")
    assert input_x in [1,2]
 
def test_b(input_x):
    print("test_b")
    assert input_x in [1,2]
 
if __name__ == '__main__':
    pytest.main(['-q','fixture_1.py'])
运行结果
fixture_1.py setup
.test_a
.test_b
teardown
setup
.test_a
.test_b
teardown

如上所示,设置scope='module',会将所有调用该fixture的用例都执行一遍,而fixture只执行了一次。

10.使用类、模块、项目中的fixture

userfixtures,可以调用在其他模块定义好的fixture.

@pytest.mark.usefixtures("x")
class TestCase:
 
    def test_1(self):
        print("test_1")
 
    def test_2(self):
        print("test_2")
 
 
if __name__ == '__main__':
    pytest.main(['-q','test_2.py'])

a.usefixture,可以添加多个fixture

@pytest.mark.usefixtures("a", "b")
def test():
    pass

b.可以使用标记机制的通用功能在测试模块级别指定fixture

pytestmark = pytest.mark.usefixtures("a")
 
def test_a():
 
def test_b():

c.可以将项目中所有测试所需的fixture放入ini文件中

#pytest.ini
 
[pytest]
usefixtures = x
 
#test_case.py
@pytest.mark.usefixtures
def test_a():
    pass

11.自动使用fixture

autouse=True

有时你可能希望自动调用fixture, 而无需显示声明函数参数或usefixtures装饰器。

import pytest
 
 
class DB:
    def __init__(self):
        self.intransaction = []
 
    def begin(self, name):
        self.intransaction.append(name)
 
    def rollback(self):
        self.intransaction.pop()
 
 
@pytest.fixture(scope="module")
def db():
    return DB()
 
 
class TestClass:
    @pytest.fixture(autouse=True)
    def transact(self, request, db):
        db.begin(request.function.__name__)
        yield
        db.rollback()
 
    def test_method1(self, db):
        assert db.intransaction == ["test_method1"]
 
    def test_method2(self, db):
        assert db.intransaction == ["test_method2"]

类级transact夹具标记有autouse = true ,这意味着该类中的所有测试方法都将使用此夹具,而无需在测试函数签名或类级usefixtures修饰器中声明它。

autouse固定装置遵循scope=关键字参数:如果有autouse固定装置,scope='session'则无论定义在何处,都只能运行一次。scope='class'表示它将每节课运行一次,依此类推。
如果在测试模块中定义了自动使用夹具,则其所有测试功能都会自动使用它。
如果在conftest.py文件中定义了自动使用的固定装置,则其目录下所有测试模块中的所有测试都将调用固定装置。
最后,请谨慎使用:如果您在插件中定义了自动使用夹具,它将在安装该插件的所有项目中的所有测试中调用它。如果固定装置仅在某些设置下(例如在ini文件中)仍然可以工作,则这很有用。这样的全局夹具应始终快速确定它是否应该做任何工作,并避免其他昂贵的导入或计算。
请注意,上面的transact灯具很可能是您希望在项目中不启用的灯具。做到这一点的规范方法是将事务处理定义放入conftest.py文件中,而无需使用autouse:

# content of conftest.py
@pytest.fixture
def transact(request, db):
    db.begin()
    yield
    db.rollback()

然后例如通过声明需要让TestClass使用它:

@pytest.mark.usefixtures("transact")
class TestClass:
    def test_method1(self):
        ...

该TestClass中的所有测试方法都将使用事务处理夹具,而模块中的其他测试类或功能将不使用它,除非它们也添加了transact引用。

fixture覆盖

1.对于测试文件夹级别,具有相同名称的fixture可以被覆盖

tests/
    __init__.py
 
    conftest.py
        # content of tests/conftest.py
        import pytest
 
        @pytest.fixture
        def username():
            return 'username'
 
    test_something.py
        # content of tests/test_something.py
        def test_username(username):
            assert username == 'username'
 
    subfolder/
        __init__.py
 
        conftest.py
            # content of tests/subfolder/conftest.py
            import pytest
 
            @pytest.fixture
            def username(username):
                return 'overridden-' + username
 
        test_something.py
            # content of tests/subfolder/test_something.py
            def test_username(username):
                assert username == 'overridden-username'

2.在测试模块中覆盖fixture

tests/
    __init__.py
 
    conftest.py
        # content of tests/conftest.py
        import pytest
 
        @pytest.fixture
        def username():
            return 'username'
 
    test_something.py
        # content of tests/test_something.py
        import pytest
 
        @pytest.fixture
        def username(username):
            return 'overridden-' + username
 
        def test_username(username):
            assert username == 'overridden-username'
 
    test_something_else.py
        # content of tests/test_something_else.py
        import pytest
 
        @pytest.fixture
        def username(username):
            return 'overridden-else-' + username
 
        def test_username(username):
            assert username == 'overridden-else-username'

3.在文件内覆盖

tests/
    __init__.py
 
    conftest.py
        # content of tests/conftest.py
        import pytest
 
        @pytest.fixture
        def username():
            return 'username'
 
        @pytest.fixture
        def other_username(username):
            return 'other-' + username
 
    test_something.py
        # content of tests/test_something.py
        import pytest
 
        @pytest.mark.parametrize('username', ['directly-overridden-username'])
        def test_username(username):
            assert username == 'directly-overridden-username'
 
        @pytest.mark.parametrize('username', ['directly-overridden-username-other'])
        def test_username_other(other_username):
            assert other_username == 'other-directly-overridden-username-other'

4.对于某些测试模块,参数化的夹具被非参数化的版本覆盖,而非参数化的夹具被参数化的版本覆盖。显然,测试文件夹级别也是如此。

tests/
    __init__.py
 
    conftest.py
        # content of tests/conftest.py
        import pytest
 
        @pytest.fixture(params=['one', 'two', 'three'])
        def parametrized_username(request):
            return request.param
 
        @pytest.fixture
        def non_parametrized_username(request):
            return 'username'
 
    test_something.py
        # content of tests/test_something.py
        import pytest
 
        @pytest.fixture
        def parametrized_username():
            return 'overridden-username'
 
        @pytest.fixture(params=['one', 'two', 'three'])
        def non_parametrized_username(request):
            return request.param
 
        def test_username(parametrized_username):
            assert parametrized_username == 'overridden-username'
 
        def test_parametrized_username(non_parametrized_username):
            assert non_parametrized_username in ['one', 'two', 'three']
 
    test_something_else.py
        # content of tests/test_something_else.py
        def test_username(parametrized_username):
            assert parametrized_username in ['one', 'two', 'three']
 
        def test_username(non_parametrized_username):
            assert non_parametrized_username == 'username'

实用技巧

1.conftest.py 共享fixture。如果定义fixture过多且需要多个地方调用,可将fixture放入conftest.py文件中,使用时不需要导入

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/240367.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Javascript高频面试题

系列文章目录 文章目录 系列文章目录前言1.JavaScript常见数据类型null 和 undefind区别symbol(ES6新增)、bigInt(ES10新增) 2.JavaScript判断数据类型的方式3. 和 区别,分别在什么情况使用?4.变量声明 va…

Unity检测AssetBundle是否循环依赖

原理:bundle的依赖关系构建一个二维的矩阵图,如果对角线相互依赖(用1标记)则表示循环依赖。 using PlasticGui; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public cl…

Redis缓存异常问题,常用解决方案总结

前言 Redis缓存异常问题分别是:1.缓存雪崩。2.缓存预热。3.缓存穿透。4.缓存降级。5.缓存击穿,以 及对应Redis缓存异常问题解决方案。 1.缓存雪崩 1.1、什么是缓存雪崩 如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有…

zabbix6入门到精通(3) 预处理

zabbix6入门到精通(3) 预处理 配置 — 主机 文件系统主项目 vfs.fs.get 测试一下 添加预处理 $[?(.fsname ‘/’)] $[0].inodes.pfree JSONPath参照: https://www.zabbix.com/documentation/6.0/zh/manual/config/items/preprocessi…

【Docker】进阶之路:(十三)Docker Swarm

目录 Docker Swarm架构与概念 Docker Swarm架构 Docker Swarm 相关概念 1.Swarm 2.Node Docker Swarm是Docker官方提供的集群管理工具,它的主要作用是将Docker主机池转变为单个虚拟Docker主机,把若干台Docker主机抽象为一个整体,并且通过…

django实现增删改查分页接口

django实现增删改查分页接口(小白必备) 在上篇文章中我使用nodejs实现了增删改查分页接口,这一篇我们则使用django实现。 1.创建一个django项目,命令如下 python manage.py startapp myapp 2.在你自己的myapp文件夹中的models.py中定义你们自己的模型 f…

java导出word使用模版与自定义联合出击解决复杂表格!

1. 看一下需要导出什么样子的表格 如图所示,这里的所有数据行都是动态的,需要根据查询出来的数据循环展示。 如果只是这样的话,使用freemarker应该都可以搞定,但是他一列中内容相同的单元格,需要合并。 这对于表格样式…

翻译: LLM大语言模型图像生成原理Image generation

文本生成是许多用户正在使用的,也是所有生成式人工智能工具中影响最大的。但生成式人工智能的一部分兴奋点也在于图像生成。目前也开始出现一些可以生成文本或图像的模型,这些有时被称为多模态模型,因为它们可以在多种模式中操作,…

配置android sudio出现的错误

导入demo工程,配置过程参考: AndroidStudio导入项目的正确方式,修改gradle配置 错误:Namespace not specified. Specify a namespace in the module’s build file. 并定位在下图位置: 原因:Android 大括号…

优雅玩转实验室服务器(二)传输文件

使用服务器最重要的肯定是传输文件了,我们不仅需要本地的一些资源上传到服务器,好进行实验,也需要将服务器计算得到的实验结果传输到本地,来进行预览或者报告撰写。 首先,由于涉及到服务器操作,我强烈推荐…

等保2.0的变化

1法律地位得到确认 《中华人民共和国网络安全法》第21条规定“国家实行网络安全等级保护制度”,要求“网络运营者应当按照网络安全等级保护制度要求,履行安全保护义务”;第31条规定“对于国家关键信息基础设施,在网络安全等级保护…

16ASM 汇编基础与Debug使用

目录 硬件运行机制 微机系统硬件组成 计算机系统组成 8086CPU组织结构 DoxBox安装 Debug使用 R命令 D命令 E命令 U命令 T命令 A命令 标志寄存器 常用机器指令 硬件运行机制 下面是一个电子器件二极管,正向加电则通,反向加电则不通 利用二…

MySQL索引_什么是索引_索引的分类_什么时候需要/不需要创建索引_优化索引_索引失效

文章目录 索引1. 什么是索引2. 索引的分类按数据结构分类按物理存储分类按字段特性分类按字段个数分类 3. 什么时候需要 / 不需要创建索引?什么时候适用索引?什么时候不需要创建索引? 4. 优化索引的方法前缀索引优化覆盖索引优化主键索引最好…

spring 笔记一 spring快速入门和配置文件详解

Spring简介 Spring是分层的 Java SE/EE应用full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核。 提供了展现层SpringMV…

基于PaddleNLP的深度学习对文本自动添加标点符号(一)

前言 目前以深度学习对文本自动添加标点符号研究很少,已知的开源项目并不多,详细的介绍就更少了,但对文本自动添加标点符号又在古文识别语音识别上有重大应用。 基于此,本文开始讲解基于PaddleNLP的深度学习对文本自动添加标点符号…

c语言注册登录+实验室物帐管理系统

实验室物帐管理系统:用户手册 1引言 本用户手册旨在为实验室物帐管理系统的使用提供指导和帮助。该系统旨在实现以下功能:仪器设备条目的输入、仪器设备的借还以及库存情况查询及修改。通过本手册,您将了解到如何正确使用该系统&#xff0c…

2023 Visual Studio Code年度十佳深色主题

2023 Visual Studio Code年度十佳深色主题 Top Ten Dark-styled Themes on Visual Studio Code in 2023 By JacksonML Microsoft Visual Studio Code(以下简称:VS Code)是微软公司开发的一款开放源代码的集成开发环境(IDE), 自问世以来&…

蓝牙在物联网中的应用,相比WIFI和NFC的优势?

蓝牙在物联网中有着广泛的应用,主要包括以下几个方面: 1、智能家居:蓝牙Mesh技术可以用于智能家居设备之间的连接和通信,实现设备的远程控制和管理。例如,通过蓝牙技术可以将智能音箱、智能电视、智能家电等设备连接起…

【深度学习】强化学习(六)基于值函数的学习方法

文章目录 一、强化学习问题1、交互的对象2、强化学习的基本要素3、策略(Policy)4、马尔可夫决策过程5、强化学习的目标函数6、值函数7、深度强化学习 二、基于值函数的学习方法 一、强化学习问题 强化学习的基本任务是通过智能体与环境的交互学习一个策略…

QT 基础篇

目录 QPushButton QT帮助文档 QT 对象树 QPushButton QPushButton是Qt图形界面控件中的一种,看英文的意思,他就是按钮,是最基本的图形控件之一。在我们的最基本的项目中,运行: 是一个空白的窗体,里面什么也没有&am…