琐碎笔记——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教程 ▐ 概述 ▐ 基础语法 ▐ 函数 …...
CSS遮罩:mask
CSS属性 mask 允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域。 // 一般用位图图片做遮罩 mask: url(~/assets/images/mask.png); mask-size: 100% 100%;// 使用 SVG 图形中的形状来做遮罩 mask: url(~/assets/images/mask.svg#star);…...
Swift闭包的本质
1 闭包的本质其实是一个引用类型:存储在堆空间上,由堆分配空间,且生命周期由ARC(自动引用计数机制)管理 2 捕获值:闭包会捕获上下文使用到的变量(引用类型会保持引用关系)ÿ…...
时代变迁对传统机器人等方向课程的巨大撕裂
2020年之后,全面转型新质课程规划,传统课程规划全部转为经验。 农耕-代表性生产关系-封建分配制度主要生产力-人力工业-代表性生产关系-资本分配制度工业分为机械时代,电气时代,信息时代;主要生产力-人力转为人脑&…...
【算法设计与分析实训】第1关:求序列的最大字段和
务描述 本关任务:编写用动态规划解决最大字段和问题。 相关知识 为了完成本关任务,你需要掌握:动态规划。 编程要求 给定由n个整数(可能为负数)组成的序列:a1,a2,……,an, 求该序列的最大子段和。当所有整…...
【澜舟科技-注册/登录安全分析报告】
前言 由于网站注册入口容易被机器执行自动化程序攻击,存在如下风险: 暴力破解密码,造成用户信息泄露,不符合国家等级保护的要求。短信盗刷带来的拒绝服务风险 ,造成用户无法登陆、注册,大量收到垃圾短信的…...
【读书笔记-《网络是怎样连接的》- 7】Chapter3_2 路由器
本篇继续介绍路由器及其转发过程。 1 路由器内部结构 路由器内部结构图如图所示。 即主要包含左侧的包转发模块和右侧的端口模块。转发模块负责查找包的发送目的地,端口模块完成包的发送。通过安装不同的硬件,转发模块不仅可以支持以太网,也…...
Android Activity 基础接口知识和常见问题
Activity 知识点及问题点 接口onMultiWindowModeChangedonConfigurationChanged 常见问题Android解决点击桌面图标,就重新启动应用程序问题 接口 onMultiWindowModeChanged 定义 onMultiWindowModeChanged是Android中Activity类的一个回调方法。它会在活动…...
利用python 检测当前目录下的所有PDF 并转化为png 格式
以下是一个完整的 Python 脚本,用于检测当前目录下的所有 PDF 文件并将每一页转换为 PNG 格式: import os from pdf2image import convert_from_path# 设置输出图像的 DPI(分辨率) DPI 300# 获取当前目录 current_directory os…...
解决 Spring Boot 中 `Ambiguous mapping. Cannot map ‘xxxController‘ method` 错误
前言 在使用 Spring Boot 开发 Web 应用时,经常会遇到各种各样的错误。其中一种常见的错误是 Ambiguous mapping. Cannot map ‘testController‘ method。本文将详细介绍这个错误的原因及解决方法,帮助开发者快速定位并解决问题。 错误解释 这个错误…...
C++ 函数返回值优化
本文中部分内容来自下面的文章,还有一部分来自智谱清言 C 返回值优化_c 局部变量返回优化-CSDN博客 elision:省略 copy elision:拷贝省略 RVO (Return Value Optimization):返回值优化 ------ 我最近也遇到了上面博文中说到的问题&…...
网站做rss+wordpress/网络营销措施有哪些
开发四年只会写业务代码,分布式高并发都不会还做程序员? 2018年,JetBrains 发起了其标准的年度调查项目,开发人员生态系统调查 (The Developer Ecosystem 2018)。现在已将全部的原始数据公布在了官网,以便…...
东莞一站式网站推广运营/网站外贸推广
为什么80%的码农都做不了架构师?>>> 亲身经历总结如下,程序员想承接上百万的大型软件项目,必须要具备以下几点必要的条件: 01:过关的软件开发技术技能,必须需要在行业内有一定的知名度…...
东莞专业做网站的公司/南京seo排名优化公司
什么是IOPS? IOPS (英文:Input/Output Operations Per Second),即每秒进行读写(I/O)操作的次数,多用于数据库等场合,衡量随机访问的性能。存储端的IOPS性能和主机端的IO是不同的,IOP…...
app开发制作全过程/武汉seo网站推广
持续集成和持续交付文档我们(程序员)有文档在耳边。 建筑文档,设计文档,用户指南,功能规范,程序规范等等。 大多数文档比没用的文档更糟糕,因为它给人一种幻想,即所有内容都被记录下…...
做网站可以不写代码/营销案例100例小故事
Linux修改时区的正确方法 CentOS和Ubuntu的时区文件是/etc/localtime,但是在CentOS7以后localtime以及变成了一个链接文件 [rootcentos7 ~]# ll /etc/localtime lrwxrwxrwx 1 root root 33 Oct 12 11:01 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai…...
上传文章网站/百度网页收录
什么是事务? 在数据库中,所谓事务是指一组逻辑操作单元即一组sql语句。当这个单元中的一部分操作失败,整个事务回滚,只有全部正确才完成提交。判断事务是否配置成功的关键点在于出现异常时事务是否会回滚 事务四大特性 1、原子性(Atomicit…...