Pytest精通指南(26)钩子函数-依赖执行(pytest-dependency)


文章目录

      • 前言
      • 应用场景
      • 插件安装
      • 注意事项
      • 参数分析
      • 函数名称依赖实现方式
      • 类下函数路径实现方式
      • 通过设置别名指定依赖
      • 定义依赖范围
      • 作用于类
      • 作用于模块
      • 作用于包
      • 作用于会话
      • 拓展-非常重要


请添加图片描述

前言

pytest-dependency的主要用途是确保测试用例按照指定的依赖关系顺序执行。

在一个复杂的测试套件中,某些测试用例可能依赖于其他测试用例的结果或状态。

pytest-dependency允许明确地定义这些依赖关系,从而确保依赖项先执行,然后再执行依赖于此的测试用例。

这意味着我们可以指定某些测试用例必须在其他测试用例成功执行后才能运行。

通过这种方式,我们可以确保测试的执行顺序与依赖关系得到正确的处理。

应用场景

  • 有序的测试执行:当测试用例之间存在逻辑依赖关系时,需要确保它们按照正确的顺序执行。
    例如,一个测试用例可能设置了某些数据,而另一个测试用例依赖于这些数据。
  • 资源准备和清理:在某些情况下,可能需要首先准备一些资源(如数据库连接、文件、网络服务等),并在所有相关测试完成后进行清理。
    pytest-dependency可以帮助你确保资源准备和清理的顺序正确。
  • 条件测试:我们可能只想在满足特定条件时再执行某些测试用例。
    pytest-dependency可以基于其他测试用例的成功或失败来执行特定的测试。

插件安装

安装命令pip install pytest-dependency

官方文档: https://pytest-dependency.readthedocs.io/en/latest/index.html

请添加图片描述

注意事项

  • 误解依赖关系:有些人可能误解了 depends 参数的含义,认为它定义了测试用例的执行顺序,但实际上它定义的是依赖关系,而不是执行顺序。
    执行顺序仍由pytest的内部机制决定,但pytest-dependency插件会在必要时跳过或重新运行测试用例以满足依赖关系。

  • 错误的使用:如果不正确地使用pytest-dependency,可能会导致测试用例之间的耦合度过高,难以维护和扩展。
    因此,应谨慎使用依赖关系,确保它们确实是必要的。

  • 插件配置问题:如果没有正确配置pytest-dependency插件,例如未安装插件或未正确地在pytest命令中包含插件,那么依赖关系将不会生效。

  • 并发执行:如果使用pytest的并发执行功能(如-n参数),请确保依赖关系不会被打乱。
    pytest-dependency和 pytest 的并发执行功能可能不完全兼容,因此需要谨慎使用。

  • 测试隔离:尽量确保每个测试用例是独立的,不依赖于其他测试用例的结果。这样可以提高测试的健壮性和可复用性。

参数分析

@pytest.mark.dependency装饰器接受以下参数,其中最常用的是 depends:

  • depends: 这是一个字符串列表,指定了当前测试用例所依赖的其他测试用例的名称。
    只有当这些依赖项都成功执行时,当前测试用例才会被执行。

  • scope: 这个参数定义了依赖关系的范围。
    默认情况下,依赖关系是在整个测试会话中有效的。
    如果设置为"session", 它会覆盖默认行为。
    如果设置为"function", 则每个函数都会创建一个新的依赖上下文。

  • names: 这个参数允许你为依赖项指定一个自定义名称,这在某些情况下可能很有用,特别是当你有多个依赖项并希望使日志或报告更清晰时。

函数名称依赖实现方式

示例代码

import pytest

# 模拟数据库
db = {}


# 模拟注册
@pytest.mark.dependency()
def test_signup():
    assert len(db.keys()) == 0
    db.setdefault("username", "root")
    db.setdefault("password", "1234")


# 模拟登录
@pytest.mark.dependency(depends=["test_signup"])
def test_login():
    # 依赖于 test_signup 的测试用例
    assert db.get("username") == "root"
    assert db.get("password") == "1234"


被依赖的测试用例执行成功结果

请添加图片描述

被依赖的测试用例执行失败结果

请添加图片描述

类下函数路径实现方式

示例代码

import pytest


class TestCase:
    @pytest.mark.dependency()
    def test_01(self):
        assert False

    @pytest.mark.dependency(depends=["TestCase::test_01"])
    def test_02(self):
        assert False

执行结果

请添加图片描述

通过设置别名指定依赖

示例代码

import pytest

# 模拟数据库
db = {}


# 模拟注册
@pytest.mark.dependency(name="1")
def test_signup():
    assert len(db.keys()) == 0
    db.setdefault("username", "root")
    db.setdefault("password", "1234")


def test_03():
    assert True


# 模拟登录
@pytest.mark.dependency(depends=["1"])
def test_login():
    # 依赖于 test_signup 的测试用例
    assert db.get("username") == "root"
    assert db.get("password") == "1234"


class TestCase:
    @pytest.mark.dependency("name")
    def test_01(self):
        assert False

    @pytest.mark.dependency(depends="name")
    def test_02(self):
        assert False

执行结果

请添加图片描述

定义依赖范围

从官方说明中我们看到scope可以接受四种参数定义的类型:

  • session
  • package
  • module
  • class

请添加图片描述

作用于类

scope=“class”

  • 作用于所属类,外部类不会被关联

示例代码

import pytest


class TestCase1:
    @pytest.mark.dependency()
    def test_01(self):
        assert False


class TestCase2:
    @pytest.mark.dependency(scope="class")
    def test_01(self):
        assert True

    @pytest.mark.dependency(depends=["test_01"], scope="class")
    def test_02(self):
        assert True

执行结果

请添加图片描述

作用于模块

scope=“module”

  • 不传递scope参数,即默认参数是module,作用于当前py文件
  • 只会查找当前文件的符合条件的文件名,类里同名的方法不会被依赖

示例代码

import pytest


@pytest.mark.dependency()
@pytest.mark.xfail(reason="模拟失败")
def test_fail():
    print("进入module::test_fail函数")
    assert False


class TestCase1:
    @pytest.mark.dependency()
    def test_01(self):
        assert False


class TestCase2:
    @pytest.mark.dependency()
    def test_fail(self):
        print("进入TestCase2::test_fail函数")
        assert True

    @pytest.mark.dependency(depends=["test_fail"])
    def test_02(self):
        assert True

执行结果

请添加图片描述

作用于包

scope=“package”

  • 作用于当前目录同级的依赖函数,跨目录无法找到依赖的函数。

test_case_01.py示例代码

import pytest


class TestCase1:
    @pytest.mark.dependency(scope="class")
    def test_01(self):
        print('测试用例01')
        assert 1 == 1

    @pytest.mark.dependency(depends=['test_01'], scope="class")
    def test_02(self):
        print('测试用例02依赖于测试用例01')
        assert True

test_case_02.py示例代码

import pytest


class TestCase2:
    @pytest.mark.dependency(
        depends=['testcase/test_case_01.py::TestCase1::test_02'],
        scope="package"
    )
    def test_03(self):
        print('测试用例03依赖于统计目录下test_case_01.py的02')
        assert True

执行结果

请添加图片描述

作用于会话

scope=“session”

  • 作用域全局,可跨目录调用。但被依赖的用例必须先执行,否则用例会执行跳过!

testcase/test_case_01.py示例代码

import pytest


class TestCase1:
    @pytest.mark.dependency(scope="class")
    def test_01(self):
        print('测试用例01')
        assert 1 == 1

    @pytest.mark.dependency(depends=['test_01'], scope="class")
    def test_02(self):
        print('测试用例02依赖于测试用例01')
        assert True

testcase/test_case_02.py示例代码

import pytest


class TestCase2:
    @pytest.mark.dependency(
        depends=['testcase/test_case_01.py::TestCase1::test_02'],
        scope="package"
    )
    def test_03(self):
        print('测试用例03依赖于统计目录下test_case_01.py的02')
        assert True

testcase2/test_case_03.py示例代码

import pytest


class TestCase3:
    @pytest.mark.dependency(
        depends=['testcase/test_case_02.py::TestCase2::test_03'],
        scope="session"
    )
    def test_04(self):
        print('测试用例04依赖于非同级目录下test_case_02.py的03')
        assert True

执行结果

请添加图片描述

拓展-非常重要

  • 当使用 pytest.mark.parametrize 对测试用例进行参数化时,每个参数组合都会产生一个独立的测试用例实例,每个实例都有一个唯一的节点ID(nodeid),这个ID包含了测试用例的路径和参数值。
  • 因此,如果依赖的上下文测试用例使用了参数化,那么仅仅通过测试函数的方法名来建立依赖关系是不够的,因为同一个测试函数可能会有多个不同的实例,每个实例的节点ID都是唯一的。
  • 为了解决这个问题,pytest-dependency 插件支持使用节点ID来建立依赖关系,而不仅仅是测试函数的方法名。你可以通过传递节点ID数组来指定依赖关系,而不是简单地传递方法名。

示例代码

import pytest


@pytest.mark.dependency()
@pytest.mark.parametrize('data', [1])
def test_a(data):
    # data = 1
    assert data == 1


@pytest.mark.dependency(depends=['test_a'])
def test_d():
    assert True


@pytest.mark.dependency(depends=['test_d'])
def test_b():
    assert 'ooo' == 'ooo'


@pytest.mark.dependency(depends=['test_b'])
def test_c():
    assert 'lll' is 'lll'

执行结果-未指定参数化改变的node信息

请添加图片描述

执行结果-指定参数化改变的node信息

请添加图片描述

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

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

相关文章

R语言绘制动态网络图Network教程WGCNA

今天分享的笔记是使用NetworkD3对WGCNA的共表达网络进行可视化,创建交互式动态网络图,展示基因之间的相互关系,可以用于转录组或者其他调控网络展示。 加权基因共表达网络分析 (WGCNA, Weighted correlation network analysis)是用来描述不同…

数值分析复习:Richardson外推和Romberg算法

文章目录 Richardson外推Romberg(龙贝格)算法 本篇文章适合个人复习翻阅,不建议新手入门使用 本专栏:数值分析复习 的前置知识主要有:数学分析、高等代数、泛函分析 本节继续考虑数值积分问题 Richardson外推 命题&a…

Python环境找不到解决方法

Python环境找不到 打开设置:Ctrl Alt S 添加Local Interpreter... 打开System Interpreter,找到本地安装的Python.exe路径,然后一路点OK Trust Project 如果打开工程时,出现如下对话框,请勾选 Trust projects in ...&…

CDN技术:全球化的数字内容快速分发系统

CDN技术:全球化的数字内容快速分发系统 在今天的互联网世界中,内容分发网络(CDN)技术起着至关重要的作用。它通过全球分布的服务器网络,快速、安全地将内容送达世界各地的用户,极大地提升了网页加载速度和…

使用 ollama 部署最新的Llama 3 70B本地模型

一、ollama是什么? 在本地启动并运行大型语言模型。运行Llama 3,Mistral, Gemma, Code Llama和其他模型。自定义并创建您自己的。 综合优点: 快速下载容器自动运行大模型,现在下载,马上上手。本地利用 cpu 运行大模型&#xff0c…

java:Java中的异常处理

目录 异常的概念与体系结构 异常的概念: 异常的体系结构: 异常的处理方式 防御式编程: 异常的抛出: 异常的捕获: finally: 代码示例: 异常的处理流程 自定义异常类 举例&#xff1a…

【Hadoop3.3.6】数据块副本放置策略及解析EditLog和FsImage

目录 一、摘要二、正文2.1 环境说明2.2 网络拓扑2.3 Hadoop副本放置策略介绍2.4 解析EditLog和Fsimage镜像文件三、小结一、摘要 通过解析存储于NameNode节点上的日志文件EditLog和镜像文件(元数据)Fsimage来反向验证HDFS的数据块副本存放策略,其目的是希望加深对Hadoop的数…

2024HVV在即| 最新漏洞CVE库(1.5W)与历史漏洞POC总结分享!

前言 也快到护网的时间了,每年的护网都是一场攻防实战的盛宴,那么漏洞库就是攻防红蓝双方人员的弹药库,红队人员可以通过工具进行监测是否存在历史漏洞方便快速打点,而蓝队则可以对资产进行梳理和监测历史漏洞,及时处理和修复,做好准备. 下面分享的…

【电控笔记5.4】pwm延迟

PWM延迟 1标准采样法 Td=MCU计算延迟+输出延迟 Tcon=电流控制周期 Ts=PWM载波周期 Td=1.5Ts(6.3节 ) 电流环跟PWM采样周期同步 2修改采样法

YOLOv5改进 | Conv篇 | 利用CVPR2024-DynamicConv提出的GhostModule改进C3(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是CVPR2024的最新改进机制DynamicConv其是CVPR2024的最新改进机制,这个论文中介绍了一个名为ParameterNet的新型设计原则,它旨在在大规模视觉预训练模型中增加参数数量,同时尽量不增加浮点运算&#x…

如何使用 ArcGIS Pro 快速为黑白地图配色

对于某些拍摄时间比较久远的地图,限于当时的技术水平只有黑白的地图,针对这种情况,我们可以通过现在的地图为该地图进行配色,这里为大家讲解一下操作方法,希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微…

kafka 命令行使用 消息的写入和读取 quickstart

文章目录 Intro命令日志zookeeper serverkafka servercreate topic && describe topic Intro Kafka在大型系统中可用作消息通道,一般是用程序语言作为客户端去调用kafka服务。 不过在这之前,可以先用下载kafka之后就包含的脚本文件等&#xff0…

ChromaDB教程

使用 Chroma DB,管理文本文档、将文本嵌入以及进行相似度搜索。 随着大型语言模型 (LLM) 及其应用的兴起,我们看到向量数据库越来越受欢迎。这是因为使用 LLM 需要一种与传统机器学习模型不同的方法。 LLM 的核心支持技术之一是…

数据库管理-第173期 OceanBase一体化Plus多模融合(20240422)

数据库管理173期 2024-04-22 数据库管理-第173期 OceanBase一体化Plus多模融合(20240422)1 架构简化2 不止融合2.1 行列混存2.2 多维使用2.3 多模JOIN 3 展望 数据库管理-第173期 OceanBase一体化Plus多模融合(20240422) 作者&…

Skill Check: Building Blocks for an LLM Application

Skill Check: Building Blocks for an LLM Application

腾讯云轻量2核4G5M服务器优惠价格165元1年,2024年多配置报价单

腾讯云轻量2核4G5M服务器优惠价格165元1年。腾讯云服务器价格表2024年最新价格,轻量2核2G3M服务器61元一年、2核2G4M服务器99元1年,三年560元、2核4G5M服务器165元一年、3年900元、轻量4核8M12M服务器646元15个月、4核16G10M配置32元1个月、8核32G配置11…

vue-element-admin vue设置动态路由 刷新页面后出现跳转404页面Bug 解决方法

做项目时遇到的这个bug,因为除了跳404之外也没太大影响,之前就一直放着没管,现在项目基本功能实现了,转头处理了一下,现在在这里记录一下解决方法 这个bug的具体情况是:设置了动态路由之后,不同…

如何在PostgreSQL中使用索引覆盖扫描提高查询性能?

文章目录 解决方案1. 创建合适的索引2. 确保查询能够使用索引覆盖扫描3. 调整查询以利用索引覆盖扫描4. 监控和调优 示例代码1. 创建索引2. 编写查询3. 检查是否使用索引覆盖扫描4. 调整索引 总结 在PostgreSQL中,索引是提高查询性能的关键工具之一。索引允许数据库…

物理机中没有VMNet1和VMNet8虚拟网卡

控制面板——网络连接——网络适配器 VMware Network Adapter VMnet1 VMware Network Adapter VMnet8 如果没有这两个虚拟网卡,虚拟机的网络会出现问题 # 解决办法-恢复虚拟网卡默认设置 1、下载并打开ccleaner,ccleaner官网:CCleaner M…

【苍穹外卖】HttpClient-快速理解入门

目录 HttpClient-快速理解&入门1. 需求2. 如何使用3. 具体示例4. 大致优点5. 大致缺点 HttpClient-快速理解&入门 1. 需求 在平常访问服务器里面的资源的时候,我们通常是通过浏览器输入网址(或者在浏览器点击某个连接)这种方式&…