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 ast
 
data = "{'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 allure
 
def 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 None
    else:
        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 None
    else:
        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 html
 
 
if __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装饰器方法介绍

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ZXing开源库生成二维码

引言 二维码&#xff08;QR Code&#xff09;作为一种快速、高容量、高密度的矩阵条码&#xff0c;已经在各行各业得到广泛应用。ZXing&#xff08;Zebra Crossing&#xff09;是一款由Google开源的Java二维码生成和解析库&#xff0c;提供了丰富的功能和易于使用的API。本篇博…

sqlmap使用教程(5)-信息获取

MySQL数据库 -b&#xff0c;用来获取数据库标识 --hostname&#xff0c;可以获取数据库服务器的主机名 -current-user&#xff0c;用来获取当前连接数据库的用户名 --users&#xff0c;获取数据库管理系统中的所有用户 --passwords&#xff0c;可以获取数据库用户密码的哈希值…

接口文档管理工具(yapi的使用)

文章目录 一、API管理工具二、yapi 接口管理工具功能权限管理项目管理页面功能接口接口创建接口配置管理界面 动态成员管理数据管理设置 三、 docker安装yapi三、使用流程四、参考 一、API管理工具 [推荐-官方描述]使用 YApi 管理 API 文档&#xff0c;测试&#xff0c; mock …

【C++干货铺】 RAII实现智能指针

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 为什么需要智能指针&#xff1f; 内存泄漏 什么是内存泄漏&#xff0c;内存泄露的危害 内存泄漏的分类 堆内存泄漏&#xff08;Heap leak&#xff09; 系统资…

LIO-SAM 论文阅读

论文链接 LIO-SAM 0. Abstract 提出了一种通过平滑和映射进行紧耦合激光雷达惯性里程计的框架 LIO-SAM&#xff0c;它实现了高精度、实时的移动机器人轨迹估计和地图构建 LIO-SAM 在因子图上制定激光雷达惯性里程计&#xff0c;允许将多种相对和绝对测量&#xff08;包括闭环…

k8s-基础知识(Pod,Deployment,ReplicaSet)

k8s职责 自动化容器部署和复制随时扩展或收缩容器容器分组group&#xff0c;并且提供容器间的负载均衡实时监控&#xff0c;即时故障发现&#xff0c;自动替换 k8s概念及架构 pod pod是容器的容器&#xff0c;可以包含多个container pod是k8s最小可部署单元&#xff0c;容器…

理解分布式存储的真实成本 - 10PB的硬件和软件

我们最近与一家大型银行的首席信息官进行了一次对话。他们是全球系统性重要银行之一——规模极其庞大。这位CIO决定将MinIO引入为数据分析计划的对象存储。这个部署从抵押贷款、交易和新闻平台收集数据&#xff0c;以运行Spark和其他分析工具&#xff0c;为银行提供洞察力。Min…

【C语言】【插入排序】

void InsertSort(int* a, int n) {int end 0, tmp 0;for (int i 0;i < n - 1;i){end i;tmp a[end 1];while (end > 0){if (a[end] > tmp){a[end 1] a[end];--end;}elsebreak;}a[end 1] tmp;} }逻辑解释&#xff1a; 变量end代表某次循环&#xff0c;要比较…

学习笔记-李沐动手学深度学习(三)(10-11,隐藏层、多层感知机、激活函数、模型超参数选择、欠过拟合)

总结 多体会&#xff08;宏观、哲学&#xff09; 【深度学习的核心】首先是要模型足够大&#xff0c;在此基础上通过各种手段 来控制模型容量&#xff0c;使得最终得到较小的泛化误差 【一般深度学习特指神经网络 这一块】 【学习的核心是要学习 本质上不变的那些核心思想&a…

MySql必知必会

41.undo log、redo log、 bin log的作用是什么&#xff1f; undo log 基本概念 undo log是一种用于撤销回退的日志&#xff0c;在数据库事务开始之前&#xff0c;MySQL会先记录更新前的数据到 undo log日志文件里面&#xff0c;当事务回滚时或者数据库崩溃时&#xff0c;可以…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用Binning像素合并功能(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用Binning像素合并功能&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机NEOAPI SDK和短曝光功能的技术背景Baumer工业相机通过CameraExplorer软件使用Binning功能Baumer工业相机通过NEOAPI SDK使用Binning功能1.引用合…

基于禁忌搜索算法的TSP路径规划matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 TSP问题描述 4.2 禁忌搜索算法原理 4.3 算法步骤 5.完整程序 1.程序功能描述 基于禁忌搜索算法的TSP路径规划,输出优化收敛曲线以及路线规划图。 2.测试软件版本以及运行结果展示 …

芯课堂 | 通过ISP升级芯片固件方法及框架

一、升级原理 芯片在应用前&#xff0c;是一颗裸片&#xff0c;内部没有任何驱动或应用程序。芯片在贴上PCB板子后&#xff0c;会实现各种功能&#xff0c;这是时候会开发对应的驱动或者应用程序&#xff0c;在芯片上面运行的程序&#xff0c;一般称之为固件&#xff08;Firmw…

线程池高手进阶:揭秘ThreadPoolExecutor的小妙招!

RejectedExecutionHandler总结 ThreadPoolExecutor 是 Java 中用于创建和管理线程池的接口&#xff0c;当线程池中的任务队列已满&#xff0c;并且线程池中的线程数量已经达到最大时&#xff0c;如果再有新的任务提交&#xff0c;就需要一个策略来处理这些无法执行的任务。它 …

antd 日期选择框增加季度预设范围

测试同学说想要有个季度的预设选择框&#xff0c;方便快速选择季度的开始和结束日期。 antd 的rangepicker是支持预设的 日期选择框 DatePicker - Ant Design 实现方法很简单&#xff0c;按照官网示例用moment初始化一下即可 获取当前一季度的开始日期时间&#xff1a; mom…

系统移植 day2 bootloader->u-boot 移植

一、栈的复习 1、满栈&#xff1a;当堆栈指针SP总是指向最后压入堆栈的数据&#xff0c;称为满栈&#xff1b; 2、空栈&#xff1a;当堆栈指针SP总是指向下一个将要放入数据的空位置&#xff0c;称为空栈&#xff1b; 满栈状态下&#xff0c;先移动指针&#xff0c;后赋值. 空…

量化交易学习1

一、股票数据基本分类 可分为&#xff08;1&#xff09;技术面数据和&#xff08;2&#xff09;基本面数据 &#xff08;1&#xff09;技术面数据 技术面数据是通过股票的历史价格和交易量等市场数据进行计算和分析得出的指标。常用的技术指标包括移动平均线、相对强弱指标、…

服务器数据恢复—EVA存储raid5硬盘离线的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌EVA某型号存储&#xff0c;底层是RAID5阵列&#xff0c;划分了若干lun。 服务器故障&分析&#xff1a; 该存储设备中raid5阵列有两块硬盘掉线&#xff0c;存储中的lun丢失。 将故障服务器存储中的所有磁盘编号后取出&#xff0c;硬件…

磁盘d盘满了怎么清理?几个步骤轻松搞定!

当您的电脑D盘快满了的时候&#xff0c;需要对电脑D盘进行清理&#xff0c;以节省空间并使电脑运转更加流畅。下面是一些电脑清理的方法和工具介绍。 一、清理磁盘 1、首先我们打开此电脑 2、然后找到我们要清理的磁盘 3、接着我们右键单击属性选项 4、然后我们点击磁盘清理 …

locust快速入门--自定义用户增长形状

背景&#xff1a; locust 默认的用户增长模式&#xff0c;不方便分析不同用户量大对服务器的压力影响。因此&#xff0c;需要对用户增加的图形进行自定义。 locust官网说明&#xff1a;https://docs.locust.io/en/stable/custom-load-shape.html 自定义不同时间段用户的数量…