(5)pytest-yield操作

1. 简介

  上一篇中,我们刚刚实现了在每个用例之前执行初始化操作,那么用例执行完之后如需要清除数据(或还原)操作,可以使用 yield 来实现。fixture通过scope参数控制setup级别,既然有setup作为用例之前前的操作,用例执行完之后那肯定也有teardown操作。
这里用到fixture的teardown操作并不是独立的函数,用yield关键字呼唤teardown操作。fixture的teardown操作并不是独立的函数,可以用yield关键字呼唤teardown操作。 

  我们之前学习的都是测试用例的前置固件,也就是相当于“setup”。说到这,细心的你可能想到了,那有没有什么方式可以表示出“teardown”?这就是我们今天学习的yield和addfinalizer。

yield

  yield是一个关键字,它不是单独存在的,要写在fixtrue标记的固件中。

  我们在声明的固件myfixture中加入yield关键字,在它下面写测试用例执行后想要运行的代码;其他有关于固件的使用没有任何差别。需要说明的一点是我们在pytest主函数中增加了一个参数“–setup-show”,他会显示出固件的执行情况。

  fixture里面的teardown用yield来唤醒teardown的执行

  如果测试用例中的代码出现异常或者断言失败,并不会影响他的固件中yield后的代码执行;但是如果固件中的yield之前的代码也就是相当于setup部分的带代码,出现错误或断言失败,那么yield后的代码将不会再执行,当然测试用例中的代码也不会执行。

  我们也可以通过request.addfinalizer()的方式实现“teardown”

  我们在固件中传入request参数;又在固件中定义了一个内置函数;最后将定义的内置函数添加到request的addfinalizer中

2. scope="function"

当 pytest.fixture(scope="function") 时,pytest的yieId 类似unittest的teartown。每个方法(函数)都会执行一次

1.新建 test_function1.py文件,我们看一下是不是这样的。

2.1 代码实现:

2.2 参考代码:
# coding=utf-8
# 1.导入模块
import pytest@pytest.fixture(scope="function")
def login():print("登录成功")yieldprint("用例执行完成,收尾")def test1(login):print('操作1')print("-----------------------------------------------")def test2(login):print('操作2')print("-----------------------------------------------")def test3(login):print('操作3')print("-----------------------------------------------")if __name__ == "__main__":pytest.main(["-s", "test.py"])
2.3 运行结果:

运行代码后,控制台打印如下图的结果

从结果看出,虽然test1,test2,test3三个地方都调用了login函数,并且它会在每一个用例前执行一次

2.如果test1不调用,test2(调用login),test3不调用,运行顺序会是怎样的?

2.4 参考代码:
# coding=utf-8
# 1.导入模块
import pytest@pytest.fixture(scope="function")
def login():print("登录成功")yieldprint("用例执行完成,收尾")def test1():print('操作1')print("-----------------------------------------------")def test2(login):print('操作2')print("-----------------------------------------------")def test3():print('操作3')print("-----------------------------------------------")if __name__ == "__main__":pytest.main(["-s", "test.py"])
2.5 运行结果:

运行代码后,控制台打印如下图的结果

从结果看出,function级别的fixture在当前.py模块里,只会在用例(test_s2)第一次调用前执行一次

3.scope="module"

1.fixture参数scope=”module”,module作用是整个.py文件都会生效( 整个文件只会执行一次),用例调用时,参数写上函数名称就行

3.1 代码实现:

3.2 参考代码:
# coding=utf-8
# 1.导入模块
import pytest@pytest.fixture(scope="module")
def login():print("登录成功")yieldprint("用例执行完成,收尾")def test1(login):print('操作1')print("-----------------------------------------------")def test2(login):print('操作2')print("-----------------------------------------------")def test3(login):print('操作3')print("-----------------------------------------------")if __name__ == "__main__":pytest.main(["-s", "test_bjhg_function1.py"])
3.3 运行结果:

运行代码后,控制台打印如下图的结果

从结果看出,虽然test1,test2,test3三个地方都调用了login函数,但是它只会在第一个用例前执行一次

2.如果test1不调用,test2(调用login),test3不调用,运行顺序会是怎样的?

3.4 参考代码:
# coding=utf-8
# 1.导入模块
import pytest@pytest.fixture(scope="module")
def login():print("登录成功")yieldprint("用例执行完成,收尾")def test1():print('操作1')print("-----------------------------------------------")def test2(login):print('操作2')print("-----------------------------------------------")def test3():print('操作3')print("-----------------------------------------------")if __name__ == "__main__":pytest.main(["-s", "test.py"])
3.5 运行结果:

运行代码后,控制台打印如下图的结果

从结果看出,module级别的fixture在当前.py模块里,只会在用例(test_s2)第一次调用前执行一次

4. yield执行teardown

  细心的童鞋或者小伙伴可以看到,我前边的代码中有一个yield关键字,大家有点好奇是做什么的,这一小节就给你答疑解惑。其实就是用来唤醒teardown。

1.fixture里面的teardown用yield来唤醒teardown的执行

4.1 代码实现:

4.2 参考代码:
# coding=utf-8
# 1.导入模块
import pytest@pytest.fixture(scope="module")
def login():print("登录成功")yieldprint("执行teardown!")print("用例执行完成,收尾")def test1(login):print('操作1')print("-----------------------------------------------")def test2(login):print('操作2')print("-----------------------------------------------")def test3(login):print('操作3')print("-----------------------------------------------")if __name__ == "__main__":pytest.main(["-s", "test.py"])
4.3 运行结果:

运行代码后,控制台打印如下图的结果

5. yield遇到异常

1.如果其中一个用例出现异常,不影响yield后面的teardown执行,运行结果互不影响,并且在用例全部执行完之后,会呼唤teardown的内容

5.1 代码实现:

5.2 参考代码:
# coding=utf-8
# 1.导入模块
import pytest@pytest.fixture(scope="module")
def login():print("登录成功")yieldprint("执行teardown!")print("用例执行完成,收尾")def test1(login):print('操作1')print("-----------------------------------------------")# 如果第一个用例异常了,不影响其他的用例执行raise NameError  # 模拟异常def test2(login):print('操作2')print("-----------------------------------------------")def test3(login):print('操作3')print("-----------------------------------------------")if __name__ == "__main__":pytest.main(["-s", "test.py"])
5.3 运行结果:

运行代码后,控制台打印如下图的结果

2.如果在setup就异常了,那么是不会去执行yield后面的teardown内容了

3.yield也可以配合with语句使用,以下是官方文档给的案例

# 官方文档案例
# content of test_yield2.pyimport smtplib
import pytest@pytest.fixture(scope="module")
def smtp():with smtplib.SMTP("smtp.gmail.com") as smtp:yield smtp  # provide the fixture value

6.addfinalizer终结函数

1.除了yield可以实现teardown,在request-context对象中注册addfinalizer方法也可以实现终结函数。

# 官方案例# content of conftest.py
import smtplib
import pytest@pytest.fixture(scope="module")
def smtp_connection(request):smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)def fin():print("teardown smtp_connection")smtp_connection.close()request.addfinalizer(fin)return smtp_connection  # provide the fixture value

2.yield和addfinalizer方法都是在测试完成后呼叫相应的代码。但是addfinalizer不同的是:

  • 他可以注册多个终结函数。

  • 这些终结方法总是会被执行,无论在之前的setup code有没有抛出错误。这个方法对于正确关闭所有的fixture创建的资源非常便利,即使其一在创建或获取时失败

参考文档:pytest documentation

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中的cmath库

在C编程中,数值计算是科学计算、工程应用及算法开发的基础。cmath库作为C标准库的重要组成部分,提供了丰富的数学函数和工具,能够高效处理各种数值计算任务。本文将全面解析cmath库的核心功能,并通过实战案例展示其强大威力。 一…

python包管理工具uv VS pip

在 Python 中,uv 和 pip 都是包管理工具,但它们的定位和特性有所不同。以下是主要区别: 1. pip(传统工具) 定位:Python 官方的包安装工具,是 Python 生态中最基础的包管理器。特点:…

OpenCv基础(C++)

1.图像读取与显示 #include<opencv2/opencv.hpp> using namespace cv;Mat src imread("C:/Users/16385/Desktop/new/photo/1.jpg");//读取图像 Mat src imread("C:/Users/16385/Desktop/new/photo/1.jpg",IMREAD_GRAYSCALE); //将读取的图像转为灰…

MySQL非阻塞创建索引的方法

文章目录 1. Online DDL (MySQL 5.6)2. pt-online-schema-change 工具3. gh-ost 工具4. 对于MySQL 8.0注意事项 在MySQL中创建大型表索引时&#xff0c;传统方式会阻塞表的写操作&#xff0c;影响生产环境使用。以下是几种非阻塞创建索引的方法&#xff1a; 1. Online DDL (My…

数字雨动画背景

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>数字雨动画背景</title><style>* {m…

分布式锁的概念与应用场景

一、分布式锁的核心概念 分布式锁是一种在分布式系统环境下&#xff0c;用于保证多个进程/节点对共享资源实现互斥访问的机制。其本质是通过某种中间件&#xff08;如Redis、ZooKeeper等&#xff09;实现跨节点的锁控制&#xff0c;确保在分布式环境中&#xff0c;同一时刻只有…

js代码09

题目 好的&#xff0c;我们继续。 在上一个练习中&#xff0c;我们深入探讨了 this 的复杂性。你会发现&#xff0c;ES6 引入的 class 语法在很大程度上就是为了简化 this 的使用&#xff0c;并为 JavaScript 提供一个更清晰、更熟悉的面向对象编程&#xff08;OOP&#xff0…

基于Airtest的App数据爬取实战:突破传统爬虫的边界

引言:App数据爬取的技术困境 在当今移动优先的时代,App已成为企业核心数据载体,然而​​传统爬虫技术​​在App数据获取上面临三大难题: ​​协议层屏障​​:加密HTTPS、SSL Pinning等技术阻断中间人攻击​​渲染层障碍​​:React Native、Flutter等跨平台框架使DOM解析…

【LeetCode 热题 100】560. 和为 K 的子数组——(解法一)前缀和+暴力

Problem: 560. 和为 K 的子数组 题目&#xff1a;给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。子数组是数组中元素的连续非空序列。 【LeetCode 热题 100】560. 和为 K 的子数组——&#xff08;解法二&#xff09;前缀和…

android车载开发之HVAC

目前主要在做车载hvac的开发&#xff0c;主要的一些功能主要是hvac&#xff0c;座椅&#xff0c;香氛&#xff0c;设置等的一些模块&#xff0c;具体模块下&#xff0c;比如 1.空调 ac&#xff0c;智能模式&#xff08;极速降温&#xff0c;极速采暖&#xff0c;智能除味&…

深度学习 Diffusers 库(自留)

&#xff08;本文将围绕 安装Diffusers库及其依赖、理解Diffusers核心概念&#xff1a;Pipeline, Model, Scheduler 、使用预训练模型进行推理&#xff08;文生图、图生图等&#xff09; 、 自定义模型和调度器 、训练自己的扩散模型&#xff08;可选&#xff0c;需要大量资源&…

【VPC技术】基础理论篇

文章目录 概述相关基础核心知识软件定义网络SDNOverlay 技术 安全组概述 参考博客 &#x1f60a;点此到文末惊喜↩︎ 概述 相关基础 基本概念 虚拟私有云VPC&#xff1a;是一个隔离的网络环境&#xff0c;每个VPC拥有专属的IP地址范围&#xff08;CIDR&#xff09;、路由表、…

在 RK3588 Ubuntu 上编译 eglinfo:全流程实战 + 常见报错修复

dv1/eglinfo 是一个开源的 EGL 信息检测工具&#xff0c;广泛用于 OpenGL ES 图形栈调试、驱动验证和嵌入式平台图形支持排查。在 Rockchip RK3588 上编译该工具可以协助我们确认 EGL DRM 是否配置正确&#xff0c;尤其在无窗口系统&#xff08;如 eglfs、framebuffer&#xf…

开源推荐:基于前后端分离架构的WMS仓储管理系统

开源推荐&#xff1a;基于前后端分离架构的WMS仓储管理系统 &#x1f525; 在线演示地址&#xff1a;https://tob.toolxq.com/wms/wms.html 点击上方链接可直接体验系统功能和界面&#xff0c;无需安装部署 前言 在企业数字化转型的浪潮中&#xff0c;仓储管理系统&#xff08…

Redis中List类型常见的操作命令有哪些?

Redis中List类型是一个字符串列表&#xff0c;这里是一些常见的命令&#xff1a; 1&#xff09;lpush:将一个或多个值插入到列表头部。列表不存在&#xff0c;一个新的列表会被创建。 2&#xff09;rpush:将一个或多个值插入到列表尾部。 3&#xff09;lpop:移除并返回列表头…

mac重复文件清理,摄影师同款清理方案

摄影师小林盯着屏幕上的警告&#xff1a;“存储空间不足”&#xff0c;离截稿只剩3小时。她的MacBook如同塞满回忆的阁楼&#xff0c;128GB的“其他”空间神秘消失。翻看照片库时&#xff0c;她惊讶地发现——同一组西藏雪山照片竟有十几个副本&#xff01;这是mac重复文件问题…

lua脚本为什么能保证原子性

Redis 处理客户端请求是基于单线程模型的&#xff08; Redis 6.0 开始引入了多线程处理网络 IO&#xff0c;但命令执行仍然是单线程的&#xff09;。这意味着&#xff0c;在任意时刻 Redis 只会执行一个命令或脚本。这种单线程特性确保了当 Redis 在执行一个 Lua 脚本时&#x…

爬虫详解:Aipy打造自动抓取代理工具

一、爬虫的本质与核心功能 爬虫是一种通过编写程序自动抓取互联网公开数据的技术工具&#xff0c;其核心流程包括&#xff1a; 模拟浏览器行为&#xff1a;发送 HTTP 请求访问目标网页解析页面结构&#xff1a;提取 HTML/XML 中的关键信息&#xff08;如文本、链接、图片&…

Leetcode百题斩-栈

终于来到了栈专题&#xff0c;想想之前来阿里的时候就是面试了一道栈最终通过了终面&#xff0c;也是十分怀念了。 739. Daily Temperatures[Medium] 思路&#xff1a;这就是最典型的单调栈问题了。从后向前维护下一个更大值或者下一个更大值的位置。 可以看一下当年面阿里时…

PIXHAWK(ardupilot4.52)NMEA的解析bug

最近在测试过程中发现在椭球高为负的地方&#xff0c;地面站读取GPS_RAW_INT (24)消息中的alt高度竟然是正值。而消息中定义的alt并不是一个unsigned数据&#xff0c;理论上是带有正负符号的。 查看gga的原始信息&#xff1a; $GPGGA,063718.40,3714.8533856,N,11845.9411766,…