pytestallure分析redis的数据并动态生成testCase报告

1.pytest.mark.parametrize 

pytest.mark.parametrize 是一个pytest的装饰器,它可以用于将参数传递给测试函数。使用 pytest.mark.parametrize 装饰器时,需要在装饰器中指定参数名称和参数值。对于多个参数,可以使用多个装饰器。

下面是一些使用 pytest.mark.parametrize 的示例:

第一个示例中,test_addition 测试函数将三个参数(x、y 和 expected)作为输入。参数值列表包含三个元组,每个元组都包含一组参数值。pytest将运行每个元组的所有参数值组合,并对每组参数值调用测试函数一次。

第二个示例中,test_uppercase 函数将两个参数(string 和 expected)作为输入。参数值列表包含两个元组,每个元组都包含一组参数值。pytest将运行每个元组的所有参数值组合,并对每组参数值调用测试函数一次。

import pytest@pytest.mark.parametrize('x, y, expected', [(1, 2, 3), (2, 3, 5), (3, 4, 7)])
def test_addition(x, y, expected):assert x + y == expected@pytest.mark.parametrize('string, expected', [('hello world', 'HELLO WORLD'), ('goodbye', 'GOODBYE')])
def test_uppercase(string, expected):assert string.upper() == expected

按照上面的例子,那么读取redis的list数据赋值给变量detail,装饰器 parametrize('detail_one',detail) 这样就可以把redis的list每条数据传到case里面了。但实际调试发现,allure.title 会显示 parametrize 的参数化,把case标题挤得很不好看:

 2.要考虑另一种写法,在 allure.title 不显示 parametrize 的参数化的具体长数据

@allure.epic("Org-文档中心")
@allure.feature("页面跳转死链接巡检")
@pytest.mark.parametrize("index", list(range(len(detail))))
def test_read_list(index):detail_dict_one = ast.literal_eval(detail[index])

parametrize 的参数化不传具体的值,而是传list的元素的数量len,在case里面 detail_dict_one = ast.literal_eval(detail[index]) 获取redis的list的每条数据。报告 allure.title 显示 parametrize 参数化的具体长数据的索引:

 3.ast.literal_eval

ast.literal_eval() 方法将该字符串转换为字典格式,ast.literal_eval() 方法是将字符串作为 Python 表达式进行评估,如果字符串可以安全地转换为字典、列表或原始类型,则返回转换后的对象。

python代码从redis的list读取的数据是字符串,如:

"{'url': 'http://**-ui.iot4-qa-group.orgapp.com/login?next=%2Frecipe', 'title': None, 'referer_url': None, 'referer_url_text': None}"

需要将这个字符串转成字典格式,以下是示例代码:

import astdata = "{'url': 'http://**-ui.iot4-qa-group.orgapp.com/login?next=%2Frecipe', 'title': None, 'referer_url': None, 'referer_url_text': None}"
converted_data = ast.literal_eval(data)
print(converted_data) # {'url': 'http://**-ui.iot4-qa-group.orgapp.com/login?next=%2Frecipe', 'title': None, 'referer_url': None, 'referer_url_text': None}

4.allure.dynamic

默认 allure 报告上的测试用例标题不设置就是用例名称,现在需要的是,当 pytest.mark.parametrize 使用每个参数值作为入参去调用一次测试函数就生成一条case。

allure 提供了在测试用例执行过程中动态指定标题和描述等标签的方法 ,allure.dynamic 是 Allure 测试报告框架中的一个装饰器,用于将动态生成的测试步骤和附件添加到测试报告中,例子:

import alluredef test_devloper_docs():"""测试用例1"""allure.dynamic.title("动态title")allure.dynamic.description_html("动态description_html")allure.dynamic.severity("blocker")allure.dynamic.feature("动态feature")allure.dynamic.story("动态story")allure.dynamic.tag("动态tag")allure.dynamic.link("https://www.baidu.com/?wd=1", "动态link")allure.dynamic.issue("https://www.baidu.com/?wd=2", "动态issue")allure.dynamic.testcase("https://www.baidu.com/?wd=3", "动态testcase")def test_demo():"""测试用例2"""allure.dynamic.description("动态description")

实际代码:

@pytest.mark.parametrize("index", list(range(len(detail))))
def test_read_list(index):"""动态设置描述"""# 获取redis的list的每条数据,并把字符串"{}"的数据转成字典格式detail_dict_one = ast.literal_eval(detail[index])# 从字典获取对应字典的数据url = detail_dict_one.get('url')title = detail_dict_one.get('title').strip() if detail_dict_one.get('title') else detail_dict_one.get('title')referer_url = detail_dict_one.get('referer_url')referer_url_text = detail_dict_one.get('referer_url_text').strip() if detail_dict_one.get('referer_url_text') else detail_dict_one.get('referer_url_text')crawled = detail_dict_one.get('crawled')spider = detail_dict_one.get('spider')# 把url转成在allure可以直接点击访问的链接url_link = f"<a href={url}>{url}</a>"referer_url_link = f"<a href={referer_url}>{referer_url}</a>"# 定义一个函数html的表格,在用例描述那里展示redis的数据description_html = format_table(url_link, title, referer_url_link, referer_url_text, crawled, spider)allure.dynamic.description_html(description_html)# 把case.title进行分类,归类到不同的story下面,方便查看if "swagger" in url:allure.dynamic.story("不需校验的链接")allure.dynamic.title(url)pytest.skip("该链接为swagger-json文档,不属于校验范围")elif title == "该页面不存在":allure.dynamic.story("链接跳转后该页面不存在")allure.dynamic.title(url)assert title != "该页面不存在"elif referer_url_text is not None and title is None:allure.dynamic.story("链接跳转后该页面标题为None")allure.dynamic.title(url)assert title is not Noneelse:allure.dynamic.story("巡检通过的链接")allure.dynamic.title(url)

5.description_html

在allure报告case的描述通过一个html表格展示redis读取的数据,定义一个函数 format_table,代码如下:

def format_table(link, title, referer_url, referer_url_text, crawled, spider):# 定义HTML样式style = """<style>table {border-collapse: collapse;width: 100%;}td, th {border: 1px solid black;text-align: left;padding: 8px;}th {background-color: #dddddd;}</style>"""# 定义表格内容table_content = f"""<table><tr><td>url</td><td>{link}</td></tr><tr><td>title</td><td>{title}</td></tr><tr><td>referer_url</td><td>{referer_url}</td></tr><tr><td>referer_url_text</td><td>{referer_url_text}</td></tr><tr><td>crawled</td><td>{crawled}</td></tr><tr><td>spider</td><td>{spider}</td></tr></table>"""# 将样式和表格内容拼接起来html = f"{style}{table_content}"# 返回HTML代码return html# 定义一个函数html的表格,在用例描述那里展示redis的数据
description_html = format_table(url_link, title, referer_url_link, referer_url_text, crawled, spider)
allure.dynamic.description_html(description_html)

Description 表格样式: 

6.完整代码

# coding=utf-8
import pytest
import allure
import os
import ast
from _redis import operate_redis# 使用lrange()方法从左到右检索整个列表并将其存储在名为detail的变量中
detail = operate_redis().find_redis_list("lrange","developer-docs:items")@allure.epic("org-文档中心")
@allure.feature("页面跳转死链接巡检")
@pytest.mark.parametrize("index", list(range(len(detail))))
def test_read_list(index):"""动态设置描述"""# 获取redis的list的每条数据,并把字符串"{}"的数据转成字典格式detail_dict_one = ast.literal_eval(detail[index])# 从字典获取对应字典的数据url = detail_dict_one.get('url')title = detail_dict_one.get('title').strip() if detail_dict_one.get('title') else detail_dict_one.get('title')referer_url = detail_dict_one.get('referer_url')referer_url_text = detail_dict_one.get('referer_url_text').strip() if detail_dict_one.get('referer_url_text') else detail_dict_one.get('referer_url_text')crawled = detail_dict_one.get('crawled')spider = detail_dict_one.get('spider')# 把url转成在allure可以直接点击访问的链接url_link = f"<a href={url}>{url}</a>"referer_url_link = f"<a href={referer_url}>{referer_url}</a>"# 定义一个函数html的表格,在用例描述那里展示redis的数据description_html = format_table(url_link, title, referer_url_link, referer_url_text, crawled, spider)allure.dynamic.description_html(description_html)# 把case.title进行分类,归类到不同的story下面,方便查看if "swagger" in url:allure.dynamic.story("不需校验的链接")allure.dynamic.title(url)pytest.skip("该链接为swagger-json文档,不属于校验范围")elif title == "该页面不存在":allure.dynamic.story("链接跳转后该页面不存在")allure.dynamic.title(url)assert title != "该页面不存在"elif referer_url_text is not None and title is None:allure.dynamic.story("链接跳转后该页面标题为None")allure.dynamic.title(url)assert title is not Noneelse:allure.dynamic.story("巡检通过的链接")allure.dynamic.title(url)def format_table(link, title, referer_url, referer_url_text, crawled, spider):# 定义HTML样式style = """<style>table {border-collapse: collapse;width: 100%;}td, th {border: 1px solid black;text-align: left;padding: 8px;}th {background-color: #dddddd;}</style>"""# 定义表格内容table_content = f"""<table><tr><td>url</td><td>{link}</td></tr><tr><td>title</td><td>{title}</td></tr><tr><td>referer_url</td><td>{referer_url}</td></tr><tr><td>referer_url_text</td><td>{referer_url_text}</td></tr><tr><td>crawled</td><td>{crawled}</td></tr><tr><td>spider</td><td>{spider}</td></tr></table>"""# 将样式和表格内容拼接起来html = f"{style}{table_content}"# 返回HTML代码return htmlif __name__ == '__main__':# pytest.main(["-s","allure-test.py"])'''-q: 安静模式, 不输出环境信息-v: 丰富信息模式, 输出更详细的用例执行信息-s: 显示程序中的print/logging输出'''pytest.main(['-s', '-q', '--clean-alluredir', '--alluredir=docs_report/report/allure-results'])os.system(r"allure generate docs_report/report/allure-results/ -o docs_report/report/allure-report --clean")

7.allure装饰器方法介绍

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

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

相关文章

数据链路层——笔记·续

使用集线器的星形拓扑 传统以太网传输媒体&#xff1a;粗同轴电缆 -> 细同轴电缆 -> 双绞线。 采用双绞线的以太网采用星形拓扑。 在星形的中心则增加了一种可靠性非常高的设备&#xff0c;叫做集线器 (hub)。 传统以太网使用同轴电缆&#xff0c;采用总线形拓扑结构&am…

嵌入式软件工程师面试题——2025校招社招通用(计算机网络篇)(二十八)

说明&#xff1a; 面试群&#xff0c;群号&#xff1a; 228447240面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但…

计算机网络 第3章(数据链路层)

系列文章目录 计算机网络 第1章&#xff08;概述&#xff09; 计算机网络 第2章&#xff08;物理层&#xff09; 计算机网络 第3章&#xff08;数据链路层&#xff09; 文章目录 系列文章目录1. 数据链路层概述1.1 概述1.2 三个重要问题 2. 封装成帧2.1 介绍2.2 透明传输2.3 总…

归一化是是什么意思,为什么要归一化

归一化 归一化是指将数据转换为标准尺度或相对比例的过程。在数据处理中&#xff0c;归一化的目标是使数据具有统一的尺度&#xff0c;以便更好地适应模型的训练和提高模型性能。归一化通常是通过线性变换将数据映射到一个特定的范围或分布。 为什么要进行归一化&#xff1f; …

RK3399平台开发系列讲解(USB篇)USB2.0 包格式分类

🚀返回专栏总目录 文章目录 一、令牌包格式二、数据包格式三、握手包格式沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 USB协议定了多种类型的包,有令牌包、数据包和握手包。 根据PID可将USB2.0的包分为四种包类型。 令牌包(Token):01B数据包(Data):11B握手包…

QT下载、安装详细教程[Qt5.15及Qt6在线安装,附带下载链接]

QT5.15及QT6的下载和安装 1.下载1.1官网下载1.2国内镜像网站下载 2.安装3.软件启动及测试程序运行3.1Qt Creator&#xff08;Community&#xff09; 1.下载 QT自Qt5.15版本后不在支持离线安装包下载(非商业版本&#xff0c;开源)&#xff0c;故Qt5.15及Qt6需要使用在线安装程序…

云原生安全:风险挑战与安全架构设计策略

概述 数字化转型已经成为当今最流行的话题之一&#xff0c;大部分企业已经开启自身的数字化转型之旅&#xff0c;在未来企业只有数字化企业和非数字化企业之分。通过数字经济的加速发展&#xff0c;可以有效推动企业数字化转型的步伐。云计算作为数字化转型的底座和重要的载体…

Redis 面试题 | 07.精选Redis高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【思路合集】talking head generation+stable diffusion

1 以DiffusionVideoEditing为baseline&#xff1a; 改进方向 针对于自回归训练方式可能导致的漂移问题&#xff1a; 训练时&#xff0c;在前一帧上引入小量的面部扭曲&#xff0c;模拟在生成过程中自然发生的扭曲。促使模型查看身份帧以进行修正。在像VoxCeleb或LRS这样的具…

webpack如何把dist.js中某个模块js打包成一个全局变量,使得在html引入dist.js后可以直接访问

webpack可以通过使用expose-loader来将模块中的一个js文件暴露为全局可以访问的变量。下面是一个示例代码&#xff1a; 1、安装expose-loader npm install expose-loader --save-dev 2、webpack.config.js配置文件 值得注意的是&#xff1a;我在本地使用16.14.2版本的node打包…

【深度学习】初识深度学习

初识深度学习 什么是深度学习 关系&#xff1a; #mermaid-svg-7QyNQ1BBaD6vmMVi {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-7QyNQ1BBaD6vmMVi .error-icon{fill:#552222;}#mermaid-svg-7QyNQ1BBaD6vmMVi .err…

【AI大模型】WikiChat超越GPT-4:在模拟对话中事实准确率提升55%终极秘密

WikiChat&#xff0c;这个名字仿佛蕴含了无尽的智慧和奥秘。它不仅是一个基于人工智能和自然语言处理技术的聊天机器人&#xff0c;更是一个能够与用户进行深度交流的智能伙伴。它的五个突出特点&#xff1a;高度准确、减少幻觉、对话性强、适应性强和高效性能&#xff0c;使得…

Airtest自动化测试工具

一开始知道Airtest大概是在年初的时候&#xff0c;当时&#xff0c;看了一下官方的文档&#xff0c;大概是类似Sikuli的一个工具&#xff0c;主要用来做游戏自动化的&#xff0c;通过截图的方式用来解决游戏自动化测试的难题。最近&#xff0c;移动端测试的同事尝试用它的poco库…

GPT5?OpenAI 创始人:GPT5 已在训练中,需要更多数据

OpenAI 最近发出征集大规模数据集的呼吁&#xff0c;特别是“今天在互联网上尚未公开轻松获取”的数据集&#xff0c;尤其是长篇写作或任何格式的对话。 GPT-5丨AI浪潮席卷全球&#xff0c;OpenAI 推出GPT-4 后&#xff0c;又于上月26日宣布今年9月、10月将推出GPT-4.5&#xf…

【LeetCode-406】根据身高重建队列(贪心)

LeetCode406.根据身高重建队列 题目描述 题目链接 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi &#xff0c;前面 正好 有 ki 个身高大于…

数据仓库-相关概念

简介 数据仓库是一个用于集成、存储和管理大量数据的系统。它用于支持企业决策制定过程中的数据分析和报告需求。数据仓库从多个来源收集和整合数据&#xff0c;并将其组织成易于查询和分析的结构。 数据仓库的主要目标是提供高性能的数据访问和分析能力&#xff0c;以便…

网络协议与攻击模拟_07UDP协议

一、简单概念 1、UDP协议简介 UDP&#xff08;用户数据报&#xff09;协议&#xff0c;是传输层的协议。不需要建立连接&#xff0c;直接发送数据&#xff0c;不会重新排序&#xff0c;不需要确认。 2、UDP报文字段 源端口目的端口UDP长度UDP校验和 3、常见的UDP端口号 5…

关于C#中的HashSet<T>与List<T>

HashSet<T> 表示值的集合。这个集合的元素是无须列表&#xff0c;同时元素不能重复。由于这个集合基于散列值&#xff0c;不能通过数组下标访问。 List<T> 表示可通过索引访问的对象的强类型列表。内部是用数组保存数据&#xff0c;不是链表。元素可重复&#xf…

深入浅出理解目标检测的NMS非极大抑制

一、参考资料 物体检测中常用的几个概念迁移学习、IOU、NMS理解 目标定位和检测系列&#xff08;3&#xff09;&#xff1a;交并比&#xff08;IOU&#xff09;和非极大值抑制&#xff08;NMS&#xff09;的python实现 Pytorch&#xff1a;目标检测网络-非极大值抑制(NMS) …

【ZYNQ入门】第九篇、双帧缓存的原理

目录 第一部分、基础知识 1、HDMI视频撕裂的原理 2、双帧缓存的原理 第二部分、代码设计原理 1、AXI_HP_WR模块 2、AXI_HP_RD模块 3、Block design设计 第三部分、总结 1、写在最后 2、更多文章 第一部分、基础知识 1、HDMI视频撕裂的原理 在调试摄像头的时候&#xf…