琐碎笔记——pytest实现前置、后置、参数化、跳过用例执行以及重试
pytest的fixture中文介绍可参考(不过文档稍微有点老):
https://www.osgeo.cn/pytest/fixture.html#what-fixtures-are
pytest各个作用域的fixture
- scope = “function”
可作用于每个用例
fixture使用的声明放在类定义前面,类中的每个用例执行时都会调用fixture装饰函数
fixture使用的声明放在用例前,用例执行时会调用fixture装饰函数 - scope = “class”
作用于整个类
fixture使用的声明放在类定义前面,类中的第一个用例执行时会调用fixture装饰函数一次
fixture使用的声明放在类中的用例前,用例执行时会调用fixture装饰函数一次,之后的用例即时有@pytest.mark.usefixtures(“fixture_class”),也不会执行 - scope = “module”
作用于整个python文件
在整个python文件中只会调用一次,
不管@pytest.mark.usefixtures(“fixture_module”)声明放在哪里(类外的用例前、类的声明前或这个类中的用例前),fixture函数都只会在整个python文件执行第一个用例时调用一次 - scope = “session”
作用于整个会话,通常可以放在conftest.py文件中,作为全局使用的前、后置步骤
在所有地方都可以使用@pytest.mark.usefixtures(“fixture_session”)
例:
import pytest@pytest.fixture(scope="function")
def fixture_function():print("fixture_function ####")@pytest.fixture(scope="class")
def fixture_class():print("fixture_class ----")@pytest.fixture(scope="module")
def fixture_module():
print("fixture_module @@@@")def test_0():print('test_0')@pytest.mark.usefixtures("fixture_class")
@pytest.mark.usefixtures("fixture_function")
class Test_class():@pytest.mark.usefixtures("fixture_module")def test_1(self):print('test_1')def test_2(self):print('test_2')def test_3(self):print('test_3')def test_4(self):print('test_4')
打印内容如下:
============================== 4 passed in 0.23s ==============================
fixture_module @@@@
fixture_class ----
fixture_function ####
PASSED [ 25%]test_1
fixture_function ####
PASSED [ 50%]test_2
fixture_function ####
PASSED [ 75%]test_3
fixture_function ####
PASSED [100%]test_4Process finished with exit code 0
1.2.pytest添加fixture装饰实现前置、后置方法
可以通过fixture夹具实现前置后置方法,后置需要使用yeild来实现。
如果一个方法或者一个类想要同时调用多个fixture。有两种方法:
- 可以使用@pytest.mark.usefixtures()进行叠加。
注意叠加顺序,先执行的后添加@pytest.mark.usefixtures语句,后执行的先添加。
需注意:与直接传入fixture不同的是,@pytest.mark.usefixtures无法获取到被fixture装饰的函数的返回值;
@pytest.mark.usefixtures的使用场景是:被测试函数需要多个fixture做前后置工作时使用; - 可以在方法中添加多个fixture函数名作为入参,执行顺序:先入参的后调用。
具体如下:
import pytestclass Test_hhh:@pytest.fixturedef setup_step1(self):print("setup_step1 @@@@")@pytest.fixturedef setup_and_teardown_step2(self):print("setup_step2 ####")yieldprint('teardown_setp2 ####\n')@pytest.mark.usefixtures("setup_step1")def test_1(self):print('test_1')@pytest.mark.usefixtures("setup_step1")@pytest.mark.usefixtures("setup_and_teardown_step2")def test_2(self):print('test_2')def test_3(self, setup_step1, setup_and_teardown_step2):print('test_3')def test_4(self, setup_and_teardown_step2):print('test_4')
setup_step1()、setup_and_teardown_step2()两个函数前添加了 @pytest.fixture 装饰,scope默认是"function"。
每次执行test_1用例之前,都会先调用setup_step1()。
每次执行test_2用例之前,都会先调用setup_and_teardown_step2(),再调用setup_step1()。
每次调用test_3用例之前,都会先调用setup_and_teardown_step2(),再调用setup_step1()。
每次调用test_4用例之前,都会先调用setup_and_teardown_step2()。
打印顺序如下:
============================== 4 passed in 0.21s ==============================
setup_step1 @@@@
PASSED [ 25%]test_1
setup_step2 ####
setup_step1 @@@@
PASSED [ 50%]test_2
teardown_setp2 ####setup_step1 @@@@
setup_step2 ####
PASSED [ 75%]test_3
teardown_setp2 ####setup_step2 ####
PASSED [100%]test_4
teardown_setp2 ####Process finished with exit code 0
pytest中各个级别的setup和teardown方法
除了使用fixture来实现前置、后置。pytest也可以直接使用setup和teardown方案实现前置、后置。pytest的前置、后置分为方法级、类级和模块级。
- 方法级:setup_method() teardown_method()
- 类级别:setup_class() teardown_class()
- 模块级:setup_module() teardown_method()
def setup_module():print("setup_module")def teardown_module():print("teardown_module")def test_1():print("test_1")assert 1 == 1class Test_learn:def setup_method(self):print("setup_method")def teardown_method(self):print("teardown_method")def setup_class(self):print("setup_class")def teardown_class(self):print("teardown_class")def test_2(self):print("test_2")assert Truedef test_3(self):print("test_3")
在整个文件中的第一个用例执行前,setup_module()会被调用。
在整个文件中的最后一个用例执行后,teardown_module()会被调用。
在类中的第一个用例执行前,setup_calss()会被调用。
在类中的最后一个用例执行后,teardown_class()会被调用。
在类中的每个用例执行前,setup_method()会被调用。
在类中的每个用例执行后,teardown_method()会被调用。
打印结果如下:
============================= test session starts =============================
collecting ... collected 3 itemstest_file.py::test_1
setup_module
test_1
PASSED
test_file.py::Test_learn::test_2
setup_classsetup_method
test_2
PASSEDteardown_methodtest_file.py::Test_learn::test_3
setup_method
test_3
PASSEDteardown_method
teardown_class
teardown_module============================== 3 passed in 0.04s ==============================
pytest参数化
可以使用@pytest.mark.parametrize进行参数化,具体用法如下:
import pytestclass Test_learn:test_data = [['正常登录', 'user1', 'password1', '登录成功'],['密码错误', 'user2', 'password2', '用户名或密码错误,请重新输入']]ids = [i[0] for i in test_data]@pytest.mark.parametrize("case, username, password, expect_text", test_data, ids=ids)def test_1(self, case, username, password, expect_text):print('\n',case,username, password, expect_text)assert Truedata2 = [{"username": "张三", "password":"123456"},{"username": "李四", "password": "123456"}]@pytest.mark.parametrize("dic",data2)def test_2(self, dic):print('\n',dic['username'], dic['password'])assert True
@pytest.mark.parametrize()中,第一个参数参数名(可以是一个或多个),第二个参数test_data为具体数据,第三个参数ids为用例名,参数名和数组中元素按顺序对应取值。
如上第一个用例中,数据有两条。第一条参数:case=‘登录成功’,username=‘user1’, password=‘password1’, expect_text=‘登录成功’;第一条用例的名称:'登录成功’。
参数的数据也可以是字典、元组等。
执行打印如下:
============================= test session starts =============================
collecting ... collected 4 itemstest_file.py::Test_learn::test_1[\u6b63\u5e38\u767b\u5f55] 正常登录 user1 password1 登录成功
PASSED
test_file.py::Test_learn::test_1[\u5bc6\u7801\u9519\u8bef] 密码错误 user2 password2 用户名或密码错误,请重新输入
PASSED
test_file.py::Test_learn::test_2[dic0] 张三 123456
PASSED
test_file.py::Test_learn::test_2[dic1] 李四 123456
PASSED============================== 4 passed in 0.04s ==============================
pytest跳过用例
- 无条件跳过用例
@pytest.mark.skip - 条件成立时,跳过用例
@pytest.mark.skipif(表达式, reason=‘跳过用例的原因’)
如:
import pytest# 会被跳过的
@pytest.mark.skipif(4%2 == 0, reason='跳过用例的原因')
def test_skip_if_true():var = 'world'assert var == 'world'# 不会被跳过的
@pytest.mark.skipif(5%2 == 0, reason='跳过用例的原因')
def test_skip_if_false():var = 2assert var == 2@pytest.mark.skip
def test_skip():var = 'HELLO'assert var == 'HELLO'
打印结果:
============================= test session starts =============================
collecting ... collected 3 itemstest_file.py::test_skip_if_true SKIPPED (跳过用例的原因)
Skipped: 跳过用例的原因test_file.py::test_skip_if_false PASSED
test_file.py::test_skip SKIPPED (unconditional skip)
Skipped: unconditional skip======================== 1 passed, 2 skipped in 0.03s =========================
pytest指定用例的执行顺序
需要安装插件:
pip install pytest-ordering
通过如下装饰器来指定执行顺序,order为整型,值越小,越先执行。
@pytest.mark.run(order=n)
n>=0的情况,有装饰器的用例比没有顺序装饰器的用例先执行;
n<0的情况,有装饰器的用例比没有顺序装饰器的用例后执行
例子:
import pytest@pytest.mark.run(order=1)
def test_1():var = 'world'assert var == 'world'@pytest.mark.run(order=0)
def test_2():var = 2assert var == 2@pytest.mark.run(order=-1)
def test_3():var = 'HELLO'assert var == 'HELLO'def test_4():assert True
执行结果:
============================= test session starts =============================
collecting ... collected 4 itemstest_file.py::test_2 PASSED
test_file.py::test_1 PASSED
test_file.py::test_4 PASSED
test_file.py::test_3 PASSED============================== 4 passed in 0.02s ==============================
pytest用例执行重试
需要安装第三方插件:
pip install pytest-rerunfailures
使用方式有两种:
-
直接在命令行指定 reruns表示最大重试次数,reruns-delay表示每次重试前的等待时间
pytest -s -q --reruns=2 --reruns-delay=5 {cases_path} --alluredir {report_path} -
使用@pytest.mark.flaky装饰器,reruns表示最大重试次数,reruns_delay表示每次重试前的等待时间,如: @pytest.mark.flaky(reruns=3, reruns_delay=2)
例:
import pytest@pytest.mark.run(order=-1)
def test_1():var = 'world'assert var == 'world'@pytest.mark.flaky(reruns=3, reruns_delay=2)
def test_4():assert False
执行结果如下,test_4执行了四次,因为执行失败进行重试而执行的有三次。
============================= test session starts =============================
collecting ... collected 2 itemstest_file.py::test_4 RERUN
test_file.py::test_4 RERUN
test_file.py::test_4 RERUN
test_file.py::test_4 FAILED
test_file.py:7 (test_4)
@pytest.mark.flaky(reruns=3, reruns_delay=2)def test_4():
> assert False
E assert Falsetest_file.py:10: AssertionErrortest_file.py::test_1 PASSED==================== 1 failed, 1 passed, 3 rerun in 6.15s =====================进程已结束,退出代码为 1
相关文章:
琐碎笔记——pytest实现前置、后置、参数化、跳过用例执行以及重试
pytest的fixture中文介绍可参考(不过文档稍微有点老): https://www.osgeo.cn/pytest/fixture.html#what-fixtures-are pytest各个作用域的fixture scope “function” 可作用于每个用例 fixture使用的声明放在类定义前面,类中的…...
C# 深层副本与浅层副本 深拷贝与浅拷贝
C# 深层副本与浅层副本 数据复制是编程中的重要任务。 对象是 OOP 中的复合数据类型。 对象中的成员字段可以按值或按引用存储。 可以以两种方式执行复制。 浅表副本将所有值和引用复制到新实例中。 引用所指向的数据不会被复制; 仅指针被复制。 新的引用指向原始…...
CH06_Lambda表达式
第6章:Lambda表达式 本章目标 为什么要学习C#编程语言 了解C#相关常识 C#开发工具Visual Studio安装 掌握C#程序的开发步骤 掌握C#的注释 掌握C#的常用转义符 本章内容 lambda表达式演变史 C# 匿名函数的演变历史可以追溯到 C# 语言的不同版本,…...
大模型本地部署实践:Ollama+Open-WebUI(MacOS)
目录 什么是Ollama Ollama安装 对话界面可视化?Open-WebUI! 安装Open-WebUI 什么是Ollama Ollama是一个为简化大语言模型本地部署与交互的开源框架。它提供了用户友好的接口,帮助开发者和模型爱好者在没有依赖外部API的基础上高效地运行、…...
JavaScript——DOM编程、JS的对象和JSON
一、DOM编程 DOM(Document Object Model)编程:就是使用document对象的API,完成对网页HTML文档进行动态修改,以实现网页数据,和样式动态变化效果的编程。 (一)DOM获取元素的多种方法 1.查找元素的函数 getElementById("id值…...
SIMCom芯讯通A7680C在线升级:FTP升级成功;http升级腾讯云对象储存的文件失败;http升级私有服务器的文件成功
从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…...
OSRM docker环境启动
命令一把梭 wget https://download.geofabrik.de/asia/china-latest.osm.pbf docker pull osrm/osrm-backend docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-extract -p /opt/car.lua /data/china-latest.osm.pbf docker run -t -v "${PWD}:/data&q…...
Vue3 动态获取 assets 文件夹图片
我真服了Vue3 这个老六了,一个简单图片src 赋值搞得那么复杂. //item.type 是我遍历类型的类型参数 <img alt"吐槽大会" :src"getAssetUrl(item.type)" /> 基于 Vue2 的Webpack 处理,还不错,可以用/ 这种绝对路径,可以接受,虽然多了个require很不爽…...
<项目代码>YOLOv8 草莓成熟识别<目标检测>
YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…...
代码随想录算法训练营第五十一天|Day51 图论
岛屿数量 深搜 https://www.programmercarl.com/kamacoder/0099.%E5%B2%9B%E5%B1%BF%E7%9A%84%E6%95%B0%E9%87%8F%E6%B7%B1%E6%90%9C.html 思路 #include <stdio.h> #define MAX_SIZE 50 int grid[MAX_SIZE][MAX_SIZE]; int visited[MAX_SIZE][MAX_SIZE]; int N, M; …...
uniapp 自定义加载组件,全屏加载,局部加载 (微信小程序)
效果图 全屏加载 页面加载使用 局部加载 列表加载里面使用 使用gif html <template><view><view class"" v-if"typeFullScreen"><view class"loading" v-if"show"><view class""><i…...
STM32完全学习——系统时钟设置
一、时钟框图的解读 首先我们知道STM32在上电初始化之后使用的是内部的HSI未经过分频直接通过SW供给给系统时钟,由于内部HSI存在较大的误差,因此我们在系统完成上电初始化,之后需要将STM32的时钟切换到外部HSE作为系统时钟,那么我…...
Github 2024-11-16Rust开源项目日报 Top10
根据Github Trendings的统计,今日(2024-11-16统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Go项目1Python项目1Lapce:用 Rust 编写的极快且强大的代码编辑器 创建周期:2181 天开发语言:Rust协议类型:Apache License 2.0St…...
CH03_反射
第3章:反射 本章目标 掌握反射的原理 熟悉反射的基本运用 本章内容 反射是什么 C# 编译运行过程 首先我们在VS点击编译的时候,就会将C#源代码编译成程序集 程序集以可执行文件 (.exe) 或动态链接库文件 (.dll) 的形式实现 程序集中包含有Microsoft …...
vue2侧边导航栏路由
<template><div><!-- :default-active"$route.path" 和index对应其路径 --><el-menu:default-active"active"class"el-menu-vertical-demo"background-color"#545c64"text-color"#fff"active-text-col…...
core 不可变类型 线程安全 record
当一个类型的对象在创建时被指定状态后,就不会再变化的对象,我们称之为不可变类型。这种类型是线程安全的,不需要进行线程同步,非常适合并行计算的数据共享。它减少了更新对象会引起各种bug的风险,更为安全。 System.D…...
linux之调度管理(8)-SMP cpu 的 psci启动
一、psci介绍 psci是arm提供的一套电源管理接口,当前一共包含0.1、0.2和1.0三个版本。它可被用于以下场景: (1)cpu的idle管理 (2)cpu hotplug以及secondary cpu启动 (3)系统shutdo…...
review-消息中间件MQ
RabbitMQ RabbitMQ,作为当今流行的开源消息代理软件,以其卓越的可靠性、灵活性和易用性在微服务架构和分布式系统中扮演着至关重要的角色。它不仅能够确保消息在不同系统组件间的高效传递,还能通过其高级消息队列协议(AMQP&#x…...
leetcode400第N位数字
代码 class Solution {public int findNthDigit(int n) {int base 1;//位数int weight 9;//权重while(n>(long)base*weight){//300n-base*weight;base;weight*10;}//n111 base3 weight900;n--;int res (int)Math.pow(10,base-1)n/base;int index n%base;return String…...
前端网页开发学习(HTML+CSS+JS)有这一篇就够!
目录 HTML教程 ▐ 概述 ▐ 基础语法 ▐ 文本标签 ▐ 列表标签 ▐ 表格标签 ▐ 表单标签 CSS教程 ▐ 概述 ▐ 基础语法 ▐ 选择器 ▐ 修饰文本 ▐ 修饰背景 ▐ 透明度 ▐ 伪类 ▐ 盒子模型 ▐ 浮动 ▐ 定位 JavaScript教程 ▐ 概述 ▐ 基础语法 ▐ 函数 …...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
