Allure:根据step动态设置description

news2024/11/17 13:55:34

背景

使用pytest+Allure进行自动化的时候,为了报告展示更明确会使用

with allure.step(xxx)

@allure.step(xxx)

测试结束后就可以看到

测试步骤

Allure还支持配置Description

之前直接在case中编写,例如

"""
[用例描述]: 专家问诊
[前置步骤]:
    1. 打开h5页面
    2. 完成登录
[测试步骤]:
    1. 点击问诊后搜索 测试医生数据
    2. 点击图文/电话/视频类型问诊
    3. 输入病情描述,选择患者
    4. 跳转至支付页面
    5. 取消订单
[编写人员]: zhongxin
"""

优点

  1. 内容清晰,由人工编写与确认

缺点

  1. 更新脚本后可能忘记同步更新

  2. 没有具体到每一步操作

新方案

新的方案采用读取执行过程中记录的step数据来展示Description

优点

  1. 根据脚本实时更新

  2. 具体到每一步的详细操作

缺点

  1. 具体程度需要根据allure.step的编写情况决定

  2. 执行失败后的步骤不会记录

  3. 不能记录后置操作

效果

 

效果

具体编码

在使用allure.step()的时候

使用的是

def __enter__(self):
    plugin_manager.hook.start_step(uuid=self.uuid, title=self.title, params=self.params)

其中start_step

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        parameters = [Parameter(name=name, value=value) for name, value in params.items()]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.allure_logger.start_step(None, uuid, step)
    def start_step(self, parent_uuid, uuid, step):
        parent_uuid = parent_uuid if parent_uuid else self._last_executable()
        if parent_uuid is None:
            self._orphan_items.append(uuid)
        else:
            self._items[parent_uuid].steps.append(step)
            self._items[uuid] = step

所以最终每个步骤都被存到了self._items里面

self._items = ThreadContextItems()

找到allure_commons.reporter.ThreadContextItems

conftest.py中编写一个函数来获取这个内容

import allure_commons

allure_commons.reporter.ThreadContextItems._thread_context.items()

然后将里面的内容解析出来

@pytest.fixture(autouse=True)
def case_end():
    yield

    for k, v in allure_commons.reporter.ThreadContextItems._thread_context.items():
        for k1, v1 in v.items():
            befores = hasattr(v1, 'befores') and getattr(v1, 'befores') or []
            steps = hasattr(v1, 'steps') and getattr(v1, 'steps') or []
            for i in befores:
                get_steps(i, base_name='前置', exclude=["_session_faker"])
            for i in steps:
                get_steps(i, base_name='\tcase')
  1. @pytest.fixture(autouse=True):每次case执行前后自动执行

  2. 第一行就是yield说明函数后面都是后置操作,在case执行结束之后才会去收集step信息

编写get_steps

因为step里面有嵌套,所以使用嵌套函数去逐步解析步骤内容

    global names
    description = []
    names = []

    def get_steps(data, base_name, exclude=None):
        if exclude is None:
            exclude = []
        global names
        name = getattr(data, 'name')
        steps = getattr(data, 'steps')
        if name and name not in exclude:
            names.append(name)
        if not steps and name:
            names_text = ""
            for index, j in enumerate(names):
                if index == 0:
                    names_text += f"<strong>{j}</strong>"
                else:
                    if index == 1:
                        names_text += "<ol>"
                    names_text += f"<li>{j}</li>"
                    if index == len(names) - 1:
                        names_text += "</ol>"
            if names_text:
                description.append(f"<p>「{base_name}」{names_text}</p>")
            names = []
            return
        if steps:
            if steps:
                for i in steps:
                    get_steps(i, base_name, exclude)

动态设置description

因为拿到的内容有很多重复,所以使用set进行去重,然后根据原列表的排序方式进行排序

    description_set = list(set(description))
    description_set.sort(key=description.index)
    description_text = "".join(description_set)
    description_text = f'<div style="line-height: 16px;font-size: 16px">{description_text}</div>'
    description = []
    allure.dynamic.description_html(description_text)

完整代码

@pytest.fixture(autouse=True)
def case_end():
    yield
    global names
    description = []
    names = []

    def get_steps(data, base_name, exclude=None):
        if exclude is None:
            exclude = []
        global names
        name = getattr(data, 'name')
        steps = getattr(data, 'steps')
        if name and name not in exclude:
            names.append(name)
        if not steps and name:
            names_text = ""
            for index, j in enumerate(names):
                if index == 0:
                    names_text += f"<strong>{j}</strong>"
                else:
                    if index == 1:
                        names_text += "<ol>"
                    names_text += f"<li>{j}</li>"
                    if index == len(names) - 1:
                        names_text += "</ol>"
            if names_text:
                description.append(f"<p>「{base_name}」{names_text}</p>")
            names = []
            return
        if steps:
            if steps:
                for i in steps:
                    get_steps(i, base_name, exclude)

    for k, v in allure_commons.reporter.ThreadContextItems._thread_context.items():
        for k1, v1 in v.items():
            befores = hasattr(v1, 'befores') and getattr(v1, 'befores') or []
            steps = hasattr(v1, 'steps') and getattr(v1, 'steps') or []
            for i in befores:
                get_steps(i, base_name='前置', exclude=["_session_faker"])
            for i in steps:
                get_steps(i, base_name='\tcase')

    description_set = list(set(description))
    description_set.sort(key=description.index)
    description_text = "".join(description_set)
    description_text = f'<div style="line-height: 16px;font-size: 16px">{description_text}</div>'
    description = []
    print(description_text)
    allure.dynamic.description_html(description_text)

资源分享

下方这份完整的软件测试视频学习教程已经上传CSDN官方认证的二维码,朋友们如果需要可以自行免费领取 【保证100%免费】

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

ScheduledExecutorService的使用及守护线程

只运行一次 private static ScheduledExecutorService scheduler; public static void main(String[] args) throws Exception { scheduler Executors.newScheduledThreadPool(5); // 循环任务&#xff0c;按照上一次任务的发起时间计算下一次任务的开始时间 scheduler.schedu…

解决mysql存储emoji表情唯一索引报错问题

问题发现&#xff1a; 1、正常上班的一天&#xff0c;突然间有运营同事反馈&#xff0c;我们在添加数据的时候&#xff0c;发现添加了&#x1f438;之后&#xff0c;对应的&#x1f4a9;没有了&#xff0c;添加了&#x1f4a9;然后&#x1f438;就没有了&#xff0c;需要研发帮…

【Linux】四、Linux 进程概念(四)|进程地址空间

目录 十、进程地址空间 10.1 回顾C/C 地址空间 10.2 测试 10.3 感性理解虚拟地址空间 10.4 如何画大饼&#xff1f; 10.5 如何理解区域划分和区域调整 10.6 虚拟地址空间、页表和物理地址 10.7 为什么存在地址空间 10.7.1 保证物理内存的安全性 10.7.2 保证进程的独立…

铁蛋白-海藻酸钠纳米包埋ACE抑制肽|海藻酸钠修饰碳纳米管(SAL-MWNTs)

铁蛋白-海藻酸钠纳米包埋ACE抑制肽|海藻酸钠修饰碳纳米管(SAL-MWNTs) 铁蛋白-海藻酸钠纳米包埋ACE抑制肽产品描述&#xff1a;利用铁蛋白在较酸条件下可逆组装特性和海藻酸钠(sodium alginate,SA)的控释作用,以马脾脱铁铁蛋白(horse spleen apoferritin,HSF)和SA作为纳米载体,…

Rust 基础(八)—— 高级特性

十九、高级特性 到目前为止&#xff0c;您已经学习了Rust编程语言最常用的部分。在我们开始第20章的下一个项目之前&#xff0c;我们先来看一下你可能偶尔会碰到&#xff0c;但不是每天都在使用的语言的一些方面。当你遇到任何未知的情况时&#xff0c;你可以使用这一章作为参…

[毕业设计]2022-2023年最新最全计算机专业毕设选题推荐汇总

目录 ①javaweb信息管理系统或web应用选题(应用开发类) ②微信小程序开发方向 ③游戏动画、数字媒体方向 ④深度学习、机器学习方向 ⑤算法研究方向 ⑥物联网、嵌入式方向 ⑦信息安全、网络安全 ⑧大数据分析、大数据预测 ⑨Matlab 选题迷茫 选题的重要性 选题指导 对毕…

Springboot利用Security做OAuth2资源服务器

Springboot利用Security做OAuth2授权验证_LO嘉嘉VE的博客-CSDN博客_springbootsecurity oauth2 密码认证 验证服务器在上一篇文章中. 验证服务器是做权限验证&#xff0c;有没有登录&#xff0c;有没有权限访问某些内容等。资源服务器指提供业务功能的服务器&#xff0c;他们…

使用idea创建springboot项目

一、第一种创建方法 点击File——>New——>Project 接下来选择空项目&#xff0c;如下图所示&#xff1a; 接下来点击Next——>项目名称——>finish 点击finish后会弹出如下图&#xff0c;让你新建一个Moudles 如下图&#xff0c; 在项目结构里面点击Modules——…

Kubeadm 部署 k8s 集群

目录 1.初始化设置 2.所有节点安装docker 3.k8s节点安装kubeadm&#xff0c;kubelet和kubectl 4.部署K8S集群 5.部署Dashboard 6.部署harbor私有仓库 名称设置组件master192.168.116.70&#xff08;2C/4G&#xff0c;cpu核心数要求大于2&#xff09;docker、kubeadm、ku…

南开大学程明明-学术规范及论文写作指导

第一讲 学术规范与论文写作-写作规范 主要内容 why writing is important 导致剽窃的原因&#xff08;引用不当也会导致&#xff09;&#xff1a; 引用不是介绍别人的工作&#xff0c;而是更加清晰介绍自己的工作 第二讲 学术规范与论文写作-WrittingTips 各种工具的使用 Ove…

s5pv210 i2c 时序

1 低层时序 ①. 底层时序 ******** 低层时序&#xff1a; ①.空闲&#xff1a; scl clk都是高电平②.起始位&#xff1a; 一个时间段&#xff0c;这个段时间内&#xff0c;SCL高电平&#xff0c; SDA 出现下降沿 &#xff0c; 接收方收到以后&#xff0c;知道了&#xff0c;…

为什么在 2023 年只使用 console.log 是一个大禁忌

这里有 5 个必须知道的控制台对象方法和技巧&#xff01; 在 2023 年&#xff0c;您是否仍在使用它console.log来满足所有 JavaScript 调试需求&#xff1f; 是时候提升您的技能并发现 JavaScript 控制台对象的全部功能了。 从console.table到console.time&#xff0c;这些高…

CFD-Post后处理,你真的会做吗?

导读&#xff1a;流体仿真中&#xff0c;解决问题通常分为四个步骤&#xff1a;几何—网格—求解—后处理。今天我们来学习最后一步&#xff1a;后处理。尤其对新手来说&#xff0c;首先要了解一下什么是后处理&#xff1f; 我们通过软件计算收敛后的得到的结果&#xff0c;只…

Python学习笔记-面向对象程序设计

记述python中关于面向对象程序设计的使用。 一、面向对象概述 面向对象&#xff08;Object Oriented&#xff09;&#xff0c;简称OO&#xff1b; 面向对象编程&#xff08;Object Oriented Programming&#xff09;&#xff0c;简称OOP。 1.对象 英文为Object&#xff0c…

IMX6ULL学习笔记(13)——GPIO接口使用【汇编方式】

一、GPIO简介 i.MX6ULL 芯片的 GPIO 被分成 5 组,并且每组 GPIO 的数量不尽相同&#xff0c;例如 GPIO1 拥有 32 个引脚&#xff0c; GPIO2 拥有 22 个引脚&#xff0c; 其他 GPIO 分组的数量以及每个 GPIO 的功能请参考 《i.MX 6UltraLite Applications Processor Reference M…

vTESTstudio入门到精通 - vTESTstudio工程创建_01

入行车载网络测试多年以来,最大的困扰就是网上几乎无法搜到工作中常见的问题答案,特别是vTESTstudio的工程和开发相关的问题,在晚上几乎就是一片未知的大陆,偶尔有几篇同行写的,基本也都是某个问题或者某个demo的创建基础讲解,至今我还未找到有博主将vTESTstudio从入门的…

艾美捷—如何选择合适的SAM甲基转移酶活性分析试剂盒?

SAM&#xff0c;也称为 AdoMet&#xff0c;充当修饰蛋白质和 DNA 所需的甲基的供体。SAM 的异常水平与许多异常有关&#xff0c;包括阿尔茨海默氏症、抑郁症、帕金森氏症、多发性硬化症、肝功能衰竭和癌症。 市面上&#xff0c;SAM甲基转移酶酶活性分析试剂盒非常少&#xff0c…

ccf历年第二题满分python代码及知识点总结(2013-2022)

201312-2ISBN号码 思路&#xff1a; 就是简单的字符串处理&#xff0c;没有什么好说的。 代码&#xff1a; str_input input() s str_input.replace("-", "") sum_value 0 start 1 for i in range(len(s)-1):sum_value int(s[i]) * startstart 1…

AI-多模态-2021:ALIGN【】

https://arxiv.org/abs/2102.05918 【写在前面】 学习良好的视觉和视觉语言表征对于解决计算机视觉问题(图像检索、图像分类、视频理解)是至关重要的&#xff0c;目前&#xff0c;预训练的特征在许多NLP任务中已经展现了非常大的潜力。虽然NLP中的表示学习已经可以用没有人工…

消息队列基础

消息队列的应用场景 异步处理&#xff0c;提升吞吐量 削峰填谷&#xff0c;平滑流量冲击 应用解耦&#xff0c;提升系统可用性 消息通讯&#xff0c;点对点消息通讯 消息模型 点对点模式 生产者生产消息到队列服务器&#xff0c;消费者消费消息&#xff0c;并发送确认收到…