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

news2024/11/19 2:43:24

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装饰器方法介绍

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

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

相关文章

【网络安全】常见的网络威胁有哪些?

随着互联网的快速发展&#xff0c;网络安全问题日益凸显。常见的网络威胁包括病毒、木马、恶意软件等。这些威胁不仅会影响计算机的安全运行&#xff0c;还会窃取用户的个人信息&#xff0c;造成巨大的损失。因此&#xff0c;我们需要采取一些措施来保护自己的网络安全。 常见的…

HarmonyOS鸿蒙应用开发( 四、重磅组件List列表组件使用详解)

List列表组件&#xff0c;是一个非常常用的组件。可以说在一个应用中&#xff0c;它的身影无处不在。它包含一系列相同宽度的列表项&#xff0c;适合连续、多行呈现同类数据&#xff0c;如商品列表、图片列表和和文本列表等。ArkUI 框架采用 List 容器组件创建列表&#xff08;…

RFID标签是什么?该技术有哪些应用领域?

射频识别&#xff08;RFID&#xff09;技术利用电磁场&#xff0c;自动识别和跟踪附在物体上的标签&#xff0c;其中&#xff0c;近场通信&#xff08;NFC&#xff09;是一种基于短距离RFID高频技术的标准&#xff0c;支持13.56 MHz的频率。 NFC技术在现今的产品中应用广泛&am…

智能GPT图书管理系统(SpringBoot2+Vue2)、接入GPT接口,支持AI智能图书馆

☀️技术栈介绍 ☃️前端主要技术栈 技术作用版本Vue提供前端交互2.6.14Vue-Router路由式编程导航3.5.1Element-UI模块组件库&#xff0c;绘制界面2.4.5Axios发送ajax请求给后端请求数据1.2.1core-js兼容性更强&#xff0c;浏览器适配3.8.3swiper轮播图插件&#xff08;快速实…

Ubuntu findfont: Font family ‘SimHei‘ not found.

matplotlib中文乱码显示 当我们遇到这样奇怪的问题时, 结果往往很搞笑 尝试1不行 Stopping Jupyter Installing font-manager: sudo apt install font-manager Cleaning the matplotlib cache directory: rm ~/.cache/matplotlib -fr Restarting Jupyter. 尝试2 This work fo…

【机组】计算机组成原理实验指导书.

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《机组 | 模块单元实验》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 ​ 目录 第一章 性能特点 1.1 系…

(音乐软件)Spotify声破天8.9.6.458

【应用名称】&#xff1a;Spotify-声破天 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#Spotify 【应用版本】&#xff1a;8.9.4 → 8.9.6 【应用大小】&#xff1a;67MB 【软件说明】&#xff1a;软件升级更新。iOS可配合qx小火箭类的工具对该软件进行解锁…

vue(vue2)使用svg格式图标

先安装插件 配置svg文件夹&#xff0c;新建icons文件&#xff0c;svg文件夹放svg后缀文件 index.js文件中的配置 import Vue from "vue" import svgIcon from "/common/iconSvg/index.vue"Vue.component(svg-icon,svgIcon) //挂载全局组件//下面…

雪洁宠物领养管理系统的设计与实现-计算机毕业设计源码58331

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

Qt解析含颜色的QString字符串显示到控件

1、需求 开发接收含颜色字符串显示到窗口&#xff0c;可解析字符串颜色配置窗口属性&#xff0c;且分割字符串显示。 mprintf(“xxxxxx”)&#xff1b;打印的xxxxxx含有颜色配置。 2、实现方法 2.1、条件 选用Qt的PlainTextEdit控件显示字符串&#xff0c;配置为只读模式 …

存内计算引领新一代技术革新,开启算力新时代

文章目录 存内计算与传统计算的区别 存内计算与传统计算的区别 存内计算芯片的优势 存内计算在各个领域的应用 存内计算技术对未来发展的影响 CSDN存内计算开发者社区&#xff1a;引领新一代技术革新的最前沿 社区内容专业度 社区具备的资源 社区的开放性 社区招募令…

网络上的诈骗:了解网络钓鱼

网络钓鱼&#xff08;Phishing&#xff09;是一种常见的网络诈骗形式&#xff0c;旨在通过假冒合法的电子通讯手段骗取个人信息、财务数据或登录凭证。 这种攻击通常涉及发送看似来自可信来源的电子邮件、短信或社交媒体消息&#xff0c;诱使受害者提供敏感信息或点击恶意链接…

前端项目部署发版流程

一、本地代码以全部提交并推送至仓库 二、项目根目录添加&#xff08;Dockerfile、nginx.conf文件&#xff09; 三、npm run build打包生成dist文件&#xff08;项目根目录&#xff09; 四、启动docker(登录状态) 五、执行命令 docker buildx build -t ‘项目的容器集群地…

【产品交互】超全面B端设计规范总结

不知不觉已经深耕在B端这个领域3年有余&#xff0c;很多人接触过B端后会觉得乏味&#xff0c;因为B端的设计在视觉上并没有C端那么有冲击力&#xff0c;更多的是结合业务逻辑&#xff0c;设计出符合业务需求的交互&#xff0c;以及界面排版的合理性&#xff0c;达到产品的可用性…

国产芯片替代趋势:发展前景与挑战全面解读

在当今数字化浪潮中&#xff0c;国产芯片替代正成为引人注目的趋势。本文将深入剖析该趋势的发展前景与挑战&#xff0c;并提供替代芯片查询的实用技巧。无论是科技从业者普通用户&#xff0c;都将在这篇文章中找到了对未来技术格局的洞察。同时&#xff0c;我们将通过上道合顺…

气象条件对铸铁平台地基深度有哪些影响呢——河北北重

气象条件对铸铁平台地基有以下影响&#xff1a; . 1.地震 地震可能导致地基的震动和错动&#xff0c;因此地震活跃区域的建筑物通常需要更深的地基以提供更大的稳定性。 2..温度变化&#xff1a;气温的变化会导致地基中的土壤膨胀和收缩&#xff0c;从而影响地基的稳定性。特…

《WebKit 技术内幕》学习之五(4): HTML解释器和DOM 模型

4 影子&#xff08;Shadow&#xff09;DOM 影子 DOM 是一个新东西&#xff0c;主要解决了一个文档中可能需要大量交互的多个 DOM 树建立和维护各自的功能边界的问题。 4.1 什么是影子 DOM 当开发这样一个用户界面的控件——这个控件可能由一些 HTML 的标签元素…

【GitHub项目推荐--人脸识别】【转载】

01 带有移动应用程序的人脸识别库 OpenFace 作为用于人脸识别的通用库&#xff0c;能够实现瞬态和移动人脸识别&#xff0c;目前在 GitHub 上斩获 14291 Star。以下为 LFW 数据集 Sylvestor Stallone 输入单个图像的流程。 项目地址&#xff1a;https://github.com/cmusatya…

新年钜惠|泰迪智能科技免费协助企业完成3个行业AI案例建模

在新年到来之际&#xff0c;为了感谢各企业一直以来对泰迪智能科技的支持&#xff0c;日前我们推出了新年钜惠活动即&#xff1a;免费协助企业完成3个行业AI案例建模。我们希望通过这样的活动&#xff0c;可以帮助更多的企业迈出AI应用的第一步&#xff0c;同时我们也希望能够为…

黑马苍穹外卖学习Day10

文章目录 Spring Task介绍cron表达式入门案例 订单状态定时处理需求分析代码开发功能测试 WebSocket介绍入门案例 来单提醒需求分析代码开发 客户催单需求分析代码开发 Spring Task 介绍 cron表达式 入门案例 订单状态定时处理 需求分析 代码开发 新建一个task包里面编写代码…