【pytest中同一个用例多次执行生成一个测试报告的方法】

为了实现主函数执行一次,而指定的测试函数(如 test_img)执行 10 次,你可以通过以下两种方式进行控制:

方法一:在 pytest 中使用 @pytest.mark.parametrize

使用 pytestparametrize 装饰器可以实现让某个测试函数运行多次。下面是一个示例,如何修改 test_img 函数使其执行 10 次:

import pytest# 使用 parametrize 装饰器执行10次测试
@pytest.mark.parametrize("run", range(10))  # 运行10次
def test_img(run):screenshot_path = "resources/base3.png"base_image_path = "resources/base1.png"boolean = check_image_similarity(screenshot_path, base_image_path, threshold=0.5)assert boolean, "两张图片不一样"

在这个例子中,pytest.mark.parametrize("run", range(10)) 会让 test_img 被执行 10 次。

方法二:在主函数中控制循环

如果你想在主函数中控制每个测试函数的执行次数,可以通过在 pytest.main() 中使用循环来执行。修改主函数如下:

if __name__ == "__main__":count = 1while True:print(f"这是第{count}轮次蓝牙、WiFi、热点、dvr压测")report_dir = "report"os.makedirs(report_dir, exist_ok=True)current_time = datetime.now().strftime("%Y%m%d_%H%M%S")report_file = os.path.join(report_dir, f"report_{current_time}.html")# 让 test_img 执行 10 次for i in range(10):try:pytest.main(["-v", "test_img.py", f"--html={report_file}"])except Exception as e:print(f"运行测试时出现错误: {e}")count += 1time.sleep(5)

在这个修改后的代码中,通过在主函数中添加一个 for i in range(10) 的循环,每次测试都执行 10 次,并在每轮次测试结束后生成相应的 HTML 报告。

方法三:使用 pytest-repeat 插件

pytest-repeat 是一个插件,允许你重复执行某个测试。首先安装插件:

pip install pytest-repeat

然后你可以通过命令行参数或代码来控制某个测试执行的次数。比如,使用下面的命令让 test_img 执行 10 次:

pytest --count=10 -v test_img.py

或者在代码中通过 @pytest.mark.repeat(10) 来控制:

import pytest@pytest.mark.repeat(10)
def test_img():screenshot_path = "resources/base3.png"base_image_path = "resources/base1.png"boolean = check_image_similarity(screenshot_path, base_image_path, threshold=0.5)assert boolean, "两张图片不一样"

示例代码:

from PIL import Image
import numpy as np
import pytest
from skimage.metrics import structural_similarity as ssim
import uiautomator2 as u2
import time
import subprocess
import os
from datetime import datetime
# 创建目录
os.makedirs('resources/images', exist_ok=True)# 截图并保存
def save_screenshot(d):current_time = datetime.now().strftime("%Y%m%d_%H%M%S")screenshot_path = f'resources/images/screenshot_{current_time}.png'd.screenshot(screenshot_path)print(f"截图已保存: {screenshot_path}")return screenshot_path  # 返回截图路径# 比较图片相似度的函数
def compare_images_similarity(image1_path, image2_path, threshold=0.5):try:img1 = Image.open(image1_path).convert('L')img2 = Image.open(image2_path).convert('L')img1 = np.array(img1)img2 = np.array(img2)if img1.shape != img2.shape:print("图片尺寸不一致")return 0.0, Falsesimilarity_index, _ = ssim(img1, img2, full=True)return similarity_index, similarity_index >= thresholdexcept Exception as e:print(f"处理图片时发生错误: {e}")return 0.0, False# 检查截图与本地存储图片的相似性
def check_image_similarity(new_screenshot, base_image, threshold=0.5):similarity, is_similar = compare_images_similarity(new_screenshot, base_image, threshold)print(f"相似度: {similarity * 100:.2f}%")if is_similar:print("两张图片相似度大于或等于指定阈值,判断为相同")return Trueelse:print("两张图片相似度小于指定阈值,判断为不同")return False
@pytest.mark.repeat(10)
def test_img():print("正在执行测试")screenshot_path = "resources/base3.png" base_image_path="resources/base1.png" boolean=check_image_similarity(screenshot_path, base_image_path, threshold=0.5)assert boolean, "两张图片图片不一样"
@pytest.mark.parametrize("run", range(10))  # 运行10次
def test_img1(run):print(f"正在执行测试,当前轮次: {run}")screenshot_path = "resources/base3.png" base_image_path="resources/base1.png" boolean=check_image_similarity(screenshot_path, base_image_path, threshold=0.5)assert boolean, "两张图片图片不一样"
if __name__ == "__main__":count = 1while True:print(f"这是第{count}轮次蓝牙、WiFi、热点、dvr压测")report_dir = "report"os.makedirs(report_dir, exist_ok=True)current_time = datetime.now().strftime("%Y%m%d_%H%M%S")report_file = os.path.join(report_dir, f"report_{current_time}.html")try:pytest.main(["-v", "test_img.py", f"--html={report_file}"])except Exception as e:print(f"运行测试时出现错误: {e}")count += 1time.sleep(5)break

总结

  • 使用 parametrize 让函数执行多次是较为简便的方式。
  • 在主函数中循环执行测试可以让你更灵活地控制多次执行。
  • 你也可以使用 pytest-repeat 插件来轻松实现重复运行某个测试。

根据你的需求,选择最适合的方式来实现这个功能。

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

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

相关文章

qt QPushButton详解

QPushButton是Qt Widgets模块中的一个基本控件,用于提供可点击的按钮。它是用户界面中最为常见和常用的控件之一,通过点击按钮,用户可以触发特定的应用程序操作。 重要方法 QPushButton(const QIcon &icon, const QString &text, QWi…

【OpenAI】第五节(图像生成)利用 OpenAI 的 DALL·E 实现自动化图像生成:从文本到图像的完整教程

引言 OpenAI 推出的 DALLE 工具因其能够生成令人惊叹的艺术作品而备受瞩目。DALLE 不仅能够生成静态图像,还能根据用户的需求进行风格化处理,创造出独特的艺术作品。通过 OpenAI 的 API,你可以轻松将 DALLE 的强大功能集成到你的 Python 程序…

《分布式机器学习模式》:解锁分布式ML的实战宝典

在大数据和人工智能时代,机器学习已经成为推动技术进步的重要引擎。然而,随着数据量的爆炸性增长和模型复杂度的提升,单机环境下的机器学习已经难以满足实际需求。因此,将机器学习应用迁移到分布式系统上,成为了一个不…

Xcode16 编译运行YYCache iOS18 sqlite3_finalize 闪退问题解决方案

问题原因 升级Xcode 16 之后,真机运行APP,发现会有Crash,崩溃堆栈线上Crash 在 YYCache 之中。如下图所示 崩溃堆栈如下: * thread #1, queue com.apple.main-thread, stop reason signal SIGABRTframe #0: 0x00000001d9391…

免费开源Odoo软件如何实现电商仓库高效发货

世界排名第一的免费开源ERP软件Odoo,拥有非常强大的仓库管理WMS功能。本文以电商仓库发货管理为例,介绍电商订单的仓库发货作业的各种方法。电商订单仓库发货流程,通常分为三个步骤,即拣货、打包、发货。根据仓库日处理订单数量的…

Token的组成部分

一、头部 通常包含两部分信息:令牌类型和签名算法。 例如在 JWT 中,头部会指明这是一个 JWT(typ字段,值为JWT),并且说明所使用的签名算法(如alg字段,可能的值包括HS256、RS256等&a…

九、pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover(悬停) 定义:发起交互的对象停留在可交互对象的交互区域。例如,当手触摸到物品表面(可交互区域)时,视为触发了Hover。 Grab(抓取) 概念&#xff…

京东笔试题

和谐敏感词 🔗 题目地址 🎉 模拟 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();String s scanner.next();String[] words new String[…

【毕业设计】基于SpringBoot的网上商城系统

前言 🔥本系统可以选作为毕业设计,运用了现在主流的SSM框架,采用Maven来帮助我们管理依赖,所选结构非常合适大学生所学的技术,非常合适作为大学的毕业设计,难以适中。 🔥采用技术:Sp…

vscode使用socks5代理ssh-remote

Host 192.168.x.x HostName 192.168.x.x User root Port 22 ProxyCommand C:\Program Files (x86)\Nmap\ncat.exe --proxy-type socks5 --proxy 127.0.0.1:1080 %h %p

aeo认证需要什么材料

AEO(Authorized Economic Operator)认证,即经认证的经营者认证,是企业信用管理体系的一种高级认证。申请AEO认证时,企业需要准备一系列的材料以证明其符合认证标准。以下是一份详细的AEO认证申请材料清单: …

C++:模板(2)

目录 非类型模板参数 模板的特化 概念 函数模板特化 类模板特化 全特化 偏特化 模板的分离编译 分离编译的概念 模板的分离编译 ​编辑 模板总结 非类型模板参数 模板参数分为类型形参与非类型形参。 类型形参:在模板参数列表中,跟在class…

linux更改系统时间

测试环境和生产环境代码完全一致,但是生产环境代码碰到了问题,报错类似time expired,猜测和系统时间有关系,修改之后确实好了。测试如下: 参考:centos7时间同步教程_centos7 时间同步,如果遇到…

HttpURLConnection构造请求体传文件

HttpURLConnection构造请求体传文件 在Java中,使用HttpURLConnection构造请求体传输文件,你需要做以下几步: 1、创建URL对象指向你想要请求的资源。 2、通过URL打开连接,转换为HttpURLConnection实例。 3、设置请求方法为POST。 …

深入解析JavaScript中的箭头函数及其在React中的应用(箭头函数与传统函数的区别、如何在不同上下文中使用箭头函数)

文章目录 1. 引言2. 箭头函数的定义与用法3. 箭头函数与传统函数的区别3.1 this绑定3.2 不能作为构造函数3.3 arguments对象 4. 如何在不同上下文中使用箭头函数4.1 在类方法中使用箭头函数4.2 在回调函数中使用箭头函数 5. 深入探讨箭头函数在React中的应用5.1 在事件处理器中…

JS之JSON.stringfy和JSON.parse

JSON.stringify 和 JSON.parse 是 JavaScript 中用于处理 JSON 数据的两个非常重要的方法。它们分别用于将 JavaScript 对象转换为 JSON 字符串,以及将 JSON 字符串解析为 JavaScript 对象。 JSON.stringify JSON.stringify 方法用于将一个 JavaScript 值&#xf…

架构演进史

软件架构是软件工程的基石,它不仅影响着系统的性能、可维护性和可扩展性,也直接关系到开发团队的效率和项目的成功。随着技术的不断发展和业务需求的变化,软件架构经历了多个阶段的演进。本文将详细探讨这些阶段及其背后的驱动因素。 1. 单体…

【Flutter】基础入门:自定义Widget

在 Flutter 开发中,除了使用丰富的内置 Widgets 构建界面外,自定义 Widget 是让你的应用更灵活和个性化的重要手段。Flutter 允许你根据需求自定义 StatelessWidget 和 StatefulWidget,以实现复杂的 UI 组件或功能模块。 本教程将通过实例讲…

GB/T28181-2022规范解读、应用场景和技术实现探究

GB/T28181-2022和GB/T28181-2016区别 GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》与 GB/T28181-2016 相比,主要有以下区别: 术语和定义方面: 术语删减:GB/T28181-2022 删除了 “联网系统信息”“数…

Win安装Redis

目录 1、下载 2、解压文件并修改名称 3、前台简单启动 4、将redis设置成服务后台启动 5、命令启停redis 6、配置文件设置 1、下载 【下载地址】 2、解压文件并修改名称 3、前台简单启动 redis-server.exe redis.windows.conf 4、将redis设置成服务后台启动 redis-server -…