琐碎笔记——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。有两种方法:

  1. 可以使用@pytest.mark.usefixtures()进行叠加。
    注意叠加顺序,先执行的后添加@pytest.mark.usefixtures语句,后执行的先添加。
    需注意:与直接传入fixture不同的是,@pytest.mark.usefixtures无法获取到被fixture装饰的函数的返回值;
    @pytest.mark.usefixtures的使用场景是:被测试函数需要多个fixture做前后置工作时使用;
  2. 可以在方法中添加多个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

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

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

相关文章

蓝桥杯c++算法学习【3】之思维与贪心(重复字符串、翻硬币、乘积最大、皮亚诺曲线距离【难】:::非常典型的必刷例题!!!)

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 思维与贪心 一、重复字符串 【问题描述】 如果一个字符串S恰好可以由某个字符串重复K次得到&#xff0c;我们就称S是K次重复字 符串…

Vue3 -- 基于Vue3+TS+Vite项目【项目搭建及初始化】

兼容性注意&#xff1a; Vite 需要 Node.js 版本 18 或 20。然而&#xff0c;有些模板需要依赖更高的 Node 版本才能正常运行&#xff0c;当你的包管理器发出警告时&#xff0c;请注意升级你的 Node 版本。【摘抄自vite官网】 这里我用的node版本是 v18.20.2 创建项目&#xf…

低代码集成多方API的简单实现

在现代软件开发中&#xff0c;集成多个API服务提供商已成为常见需求。然而&#xff0c;不同的API认证机制和数据格式使得集成过程变得复杂且耗时。为了应对这些挑战&#xff0c;本文将介绍一种低代码解决方案&#xff0c;通过配置化管理和简化的代码逻辑&#xff0c;帮助开发者…

C++ 编程基础(5)类与对象 | 5.8、面向对象五大原则

文章目录 一、面向对象五大原则1、单一功能&#xff08;Single Responsibility Principle, SRP&#xff09;2、开放封闭原则&#xff08;Open/Closed Principle, OCP&#xff09;3、里氏替换原则&#xff08;Liskov Substitution Principle, LSP&#xff09;4、接口隔离原则&am…

计算机网络中的域名系统(DNS)及其优化技术

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 计算机网络中的域名系统&#xff08;DNS&#xff09;及其优化技术 计算机网络中的域名系统&#xff08;DNS&#xff09;及其优化…

STM32单片机CAN总线汽车线路通断检测

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着汽车电子技术的不断发展&#xff0c;车辆通信接口在汽车电子控…

第二十一课 Vue组件实用示例

Vue组件实用示例 本课主要介绍组件的一些小练习&#xff0c;通过这些小练习巩固下之前课程中的学习 1&#xff09;组件中值的双向绑定 <div id"app"><test></test> </div> <script>Vue.component(test, {template: <div><…

(实战)WebApi第13讲:怎么把不同表里的东西,包括同一个表里面不同的列设置成不同的实体,所有的给整合到一起?【前端+后端】、前端中点击标签后在界面中显示

一、实现全局跨域&#xff1a;新建一个Controller&#xff0c;其它的controller都继承它 1、新建BaseController 2、在后端配置&#xff0c;此处省略【详情见第12讲四、3、】 3、其它的控制器继承BaseController&#xff0c;这个时候就能够完成全局的跨域 【向后台传cookie和…

前缀和技巧解析

前缀和技巧解析 前缀和&#xff08;Prefix Sum&#xff09;是一种常用的算法技巧&#xff0c;用于高效地处理一系列连续子数组和的问题。通过构建一个额外的数组来存储从数组起始位置到当前位置的累计和&#xff0c;可以在常数时间内快速计算任意区间的和。 前缀和应用的典型…

云安全之云计算基础

0x00 前言 本文主要是针对云计算相关的基础梳理和整理。 云计算 NIST 800-145ISO/IEC 17788ISO/IEC 17789云安全 NIST 500-299 云安全ISO / IEC FDIS 27017 云安全0x01 云计算基础 什么是云计算: 一种新的运作模式和一组用于管理计算资源共享池的技术。云计算是一种颠覆性的…

Mysql每日一题(行程与用户,困难※)

今天给大家分享一个截止到目前位置&#xff0c;我遇到最难的一道mysql题目&#xff0c;非常建议大家亲手做一遍 完整代码如下&#xff0c;这道题的主要难点是它有两个外键&#xff0c;以前没遇到过&#xff0c;我也没当回事&#xff0c;分享一下错误经验哈 当时我写的where判断…

离线 快速搭建 docker docker-compose k8s 环境

所需资源 sealos_5.0.1_linux_arm64.tar.gzkubernetes.tar等docker-compose-linux-aarch64 离线安装sealos&#xff0c;用于安装k8sdocker 首先安装sealos工具 tar zxvf sealos_5.0.1_linux_arm64.tar.gz sealos && chmod x sealos && mv sealos /usr/bin*…

Python的Web请求:requests库入门与应用

Python的Web请求&#xff1a;requests库入门与应用 在Python中&#xff0c;进行网络请求和获取数据是许多应用程序的基础功能。requests库是Python中最流行的HTTP库之一&#xff0c;它以简洁、易用、功能强大的特点著称&#xff0c;可以帮助开发者高效地进行各种类型的Web请求…

已解决:spark代码中sqlContext.createDataframe空指针异常

这段代码是使用local模式运行spark代码。但是在获取了spark.sqlContext之后&#xff0c;用sqlContext将rdd算子转换为Dataframe的时候报错空指针异常 Exception in thread "main" org.apache.spark.sql.AnalysisException: java.lang.RuntimeException: java.lang.Nu…

【Electron】Electron Forge如何支持Element plus?

在 Electron Forge 项目中集成 Element Plus 是一个相对直接的过程。Element Plus 是一个基于 Vue 3 的 UI 组件库&#xff0c;因此你需要确保你的 Electron 项目已经集成了 Vue 3。以下是集成 Element Plus 到 Electron Forge 项目的步骤&#xff1a; 1. 初始化 Electron For…

WebGIS四大地图框架:Leaflet、OpenLayers、Mapbox、Cesium

地理信息系统&#xff08;GIS&#xff09;已经成为现代应用开发中不可或缺的一部分&#xff0c;尤其在前端开发中。随着Web技术的快速发展&#xff0c;许多强大而灵活的GIS框架涌现出来&#xff0c;为开发人员提供了丰富的工具和功能&#xff0c;使他们能够创建交互式、高性能的…

cooladmin 后端 查询记录

查询记录&#xff1a;pageQueryOp中列表查询的group by node ts controller代码如下 import { CoolController, BaseController } from cool-midway/core; import { Inject, Post, Get, Param } from midwayjs/decorator; import { ComparePricesPlanInfoEntity } from ../../…

UE5运行时创建slate窗口

加入"Slate","SlateCore"模块 Actor.cpp // Fill out your copyright notice in the Description page of Project Settings.#include "MyWindowClass.h"// Sets default values AMyWindowClass::AMyWindowClass() {// Set this actor to call…

react 受控组件和非受控组件

在 React 中&#xff0c;受控组件和非受控组件是两种处理表单元素&#xff08;如输入框、选择框等&#xff09;值的方式。 1. 受控组件 受控组件是指 React 组件的表单元素的值是由 React 组件的 state 来管理的。换句话说&#xff0c;React 会全程控制表单元素的值&#xff…

cesium 3DTiles之pnts格式详解

Point Cloud 1 概述 点云&#xff08;Point Cloud&#xff09;瓦片格式用于高效流式传输大规模点云数据&#xff0c;常用于 3D 可视化中。每个点由位置&#xff08;Position&#xff09;和可选的属性定义&#xff0c;这些属性用来描述点的外观&#xff08;如颜色、法线等&…