Jmeter——结合Allure展示测试报告

news2024/12/24 19:52:30

在平时用jmeter做测试时,生成报告的模板,不是特别好。大家应该也知道allure报告,页面美观。

先来看效果图,报告首页,如下所示:

在这里插入图片描述

报告详情信息,如下所示:

在这里插入图片描述

运行run.py文件,运行成功,如下所示:

在这里插入图片描述

接下来来看下实现过程。

安装allure

allure是开源的,直接到github上下载即可。就不细说了。需要注意的是,环境变量的配置,allure的bin路径,需要配置到环境变量path中。

jmeter配置

找到bin目录下的 jmeter.properties 配置文件,将如下所示对应配置取消注释,jmeter.save.saveservice.output_format 修改为xml。

# This section helps determine how result data will be saved.
# The commented out values are the defaults.

# legitimate values: xml, csv, db.  Only xml and csv are currently supported.
jmeter.save.saveservice.output_format=xml

# The below properties are true when field should be saved; false otherwise
#
# assertion_results_failure_message only affects CSV output
#jmeter.save.saveservice.assertion_results_failure_message=true
#
# legitimate values: none, first, all
#jmeter.save.saveservice.assertion_results=none
#
jmeter.save.saveservice.data_type=true
jmeter.save.saveservice.label=true
jmeter.save.saveservice.response_code=true
# response_data is not currently supported for CSV output
jmeter.save.saveservice.response_data=true
# Save ResponseData for failed samples
jmeter.save.saveservice.response_data.on_error=true
jmeter.save.saveservice.response_message=true
jmeter.save.saveservice.successful=true
jmeter.save.saveservice.thread_name=true
jmeter.save.saveservice.time=true
jmeter.save.saveservice.subresults=true
jmeter.save.saveservice.assertions=true
jmeter.save.saveservice.latency=true
# Only available with HttpClient4
jmeter.save.saveservice.connect_time=true
jmeter.save.saveservice.samplerData=true
jmeter.save.saveservice.responseHeaders=true
jmeter.save.saveservice.requestHeaders=true
jmeter.save.saveservice.encoding=true
jmeter.save.saveservice.bytes=true
# Only available with HttpClient4
jmeter.save.saveservice.sent_bytes=true
jmeter.save.saveservice.url=true
jmeter.save.saveservice.filename=true
jmeter.save.saveservice.hostname=true
jmeter.save.saveservice.thread_counts=true
jmeter.save.saveservice.sample_count=true
jmeter.save.saveservice.idle_time=true

# Timestamp format - this only affects CSV output files
# legitimate values: none, ms, or a format suitable for SimpleDateFormat
jmeter.save.saveservice.timestamp_format=ms
jmeter.save.saveservice.timestamp_format=yyyy/MM/dd HH:mm:ss.SSS

生成jmeter结果文件

使用命令 jmeter -n -t C:\Users\Desktop\auth.jmx -l C:\Users\Desktop\result.xml 即可生成xml文件

安装依赖包

按项目中的 requirements.txt 文件,安装对应的依赖包即可。

文件解析生成allure报告

文件解析

xml文件内容如下:

在这里插入图片描述

从上述的内容,我们可以分析得出如下内容:

t 从请求开始到响应结束的时间
ts 表示访问的时刻: date
s 运行的结果
lb 表示标题
rc 返回的响应码
rm 响应信息
tn 线程的名字
assertionResult: 断言信息
responseData/samplerData: 返回数据
queryString: 请求信息

代码实现

利用生成的结果文件生成pytest的参数化数据

try:
    converte_data = xmltodict.parse(result_file, encoding='utf-8')
    sample_keys = list(converte_data['testResults'].keys())
    result = []
    ws_result = []
    sample_result = converte_data['testResults']['httpSample'] if isinstance(
        converte_data['testResults']['httpSample'],
        list) else [converte_data['testResults']['httpSample']]
    if 'sample' in sample_keys:
        ws_result = converte_data['testResults']['sample'] if isinstance(converte_data['testResults']['sample'],
                                                                         list) else [
            converte_data['testResults']['sample']]
    result_data = sample_result + ws_result
    for data in result_data:
        time = data['@t'] if '@t' in data else ''
        date = data['@ts'] if '@ts' in data else ''
        status = data['@s'] if '@s' in data else ''
        title = data['@lb'] if '@lb' in data else ''
        status_code = data['@rc'] if '@rc' in data else ''
        status_message = data['@rm'] if '@rm' in data else ''
        thread = data['@tn'] if '@tn' in data else ''
        assertion = data['assertionResult'] if 'assertionResult' in data else ''
        response_data = data['responseData']['#text'] if 'responseData' in data and '#text' in data['responseData'] \
            else ''
        sampler_data = data['samplerData']['#text'] if 'samplerData' in data and '#text' in data['samplerData'] \
            else ''
        request_data = data['queryString']['#text'] if 'queryString' in data and '#text' in data[
            'queryString'] else ''
        request_header = data['requestHeader']['#text'] if 'requestHeader' in data and '#text' in data[
            'requestHeader'] else ''
        request_url = data['java.net.URL'] if 'java.net.URL' in data else ''
        story = '未标记'
        assertion_name, assertion_result = None, None
        if status == 'false':
            assertion_name, assertion_result = get_assertion(assertion)

        meta_data = (
            time, date, status, story, title, status_code, status_message, thread, assertion_name, assertion_result,
            response_data
            , sampler_data, request_data, request_header, request_url)
        result.append(meta_data)
    return result
except Exception as e:
    print(e)
    return [
        ('time', 'date', 'true', 'story', 'title', 'status_code', 'status_message', 'thread', 'assertion_name',
         'assertion_result',
         'response_data', 'sampler_data', 'request_data', 'request_header', 'request_url')]

用例详情字段

@allure.step('用例名称:{title}')
    def title_step(self, title):
        pass

    @allure.step('请求信息')
    def request_step(self, request_url, request_header, request_data, sampler_data):
        pass

    @allure.step('断言信息')
    def assert_step(self, assertion_name, assertion_result):
        assert False

    @allure.step('文件信息:{thread}')
    def file_step(self, thread):
        pass

    @allure.step('返回信息')
    def response_step(self, status_code, status_message, response_data):
        pass

    @allure.step('附件(全部信息)')
    def attach_all(self, data):
        allure.attach(str(data), name='attach_all_data',
                      attachment_type=allure.attachment_type.JSON)

    def base_step(self, time, date, status, title, status_code, status_message, thread, assertion_name,
                  assertion_result, response_data,
                  sampler_data, request_data, request_header,
                  request_url):
        data = {'title': title, 'thread': thread, 'request_url': request_url, 'request_header': request_header,
                'request_data': request_data, 'sampler_data': sampler_data, 'status_code': status_code,
                'response_data': response_data, 'assertion_name': assertion_name, 'assertion_resul': assertion_result}
        self.file_step(thread)
        self.title_step(title)
        self.request_step(request_url, request_header, request_data, sampler_data)
        self.response_step(status_code, status_message, response_data)
        self.attach_all(data)
        if status == 'false':
            self.assert_step(assertion_name, assertion_result)
            assert False
        else:
            assert True

    @allure.title("{title}")
    @allure.feature("失败信息")
    @pytest.mark.parametrize(
        "time,date,status,story,title,status_code,status_message,thread,assertion_name,assertion_result,response_data,sampler_data,request_data,request_header,"
        "request_url",
        xml_2_data(type=1))
    def test_gjw(self, time, date, status, story, title, status_code, status_message, thread, assertion_name,
                    assertion_result,
                    response_data, sampler_data, request_data, request_header,
                    request_url):
        # allure.dynamic.story(story)
        self.base_step(time, date, status, title, status_code, status_message, thread, assertion_name, assertion_result,
                       response_data,
                       sampler_data, request_data, request_header,
                       request_url)

处理报告转化时间一致

def report_edit(env):
    path = os.path.join(Path().get_report_path(), env, 'data')
    # 批量更新聚合文件
    for file in os.listdir(path):
        if '.json' in file and 'categories' not in file:
            try:
                with open(os.path.join(path, file), 'r') as f:
                    json_str = json.loads(f.read())
                    for data in json_str['children'][0]['children']:
                        name = data['name']
                        for meta in result:
                            if name == meta[3]:
                                data['time']['start'] = int(meta[1])
                                data['time']['stop'] = int(meta[1]) + int(meta[0])
                                data['time']['duration'] = int(meta[0])
                    with open(os.path.join(path, file), 'w') as w:
                        json.dump(json_str, w, indent=2, sort_keys=True, ensure_ascii=False)
            except Exception as e:
                print(e)
    # 批量更新case文件
    cases_path = os.path.join(path, 'test-cases')
    for file in os.listdir(cases_path):
        if '.json' in file and 'categories' not in file:
            try:
                with open(os.path.join(cases_path, file), 'r') as f:
                    json_str = json.loads(f.read())
                    name = json_str['name']
                    for meta in result:
                        if name == meta[3]:
                            json_str['time']['start'] = int(meta[1])
                            json_str['time']['stop'] = int(meta[1]) + int(meta[0])
                            json_str['time']['duration'] = int(meta[0])
                    with open(os.path.join(cases_path, file), 'w') as w:
                        json.dump(json_str, w, indent=2, sort_keys=True, ensure_ascii=False)
            except Exception as e:
                print(e)

上述只是部分代码,完整代码已上传,JmeterAllureReport ,有兴趣的可以再完善。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

在这里插入图片描述

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!   

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

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

相关文章

Java笔记:认识一下class文件

1.class文件概述 我们可任意打开一个Class文件(使用Hex Editor等工具打开),内容如下(内容是16进制): 十六进制转字符串:http://www.bejson.com/convert/ox2str/ 进制转换网址(十六进…

谷歌浏览器jsonView插件安装与使用

1、打开 https://github.com ; 2、搜索 jsonView 链接:https://gitee.com/wangl2020/chrome_JSONVue 3、选择需要的插件我是选这个; 4、点击【Download Zip】,插件下载完成,解压缩到相应目录(D:\Downloa…

外贸电商独立站的选品和运营

第一步:选品 做出口跨境电商卖家,最难回答的问题就是我要卖什么产品?销量好的产品,竞争太激烈;价格很高的又卖不动;太小众的又担心客户不好开发,很纠结! 的确,对于出口B2…

若依cloud -【 100 ~ 103 】

100 分布式日志介绍 | RuoYi 分布式日志就相当于把日志存储在不同的设备上面。比如若依项目中有ruoyi-modules-file、ruoyi-modules-gen、ruoyi-modules-job、ruoyi-modules-system四个应用,每个应用都部署在单独的一台机器里边,应用对应的日志的也单独存…

数据结构-----堆(完全二叉树)

目录 前言 一.堆 1.堆的概念 2.堆的存储方式 二.堆的操作方法 1.堆的结构体表示 2.数字交换接口函数 3.向上调整(难点) 4.向下调整(难点) 5.创建堆 6.堆的插入 7.判断空 8.堆的删除 9.获取堆的根(顶)元素 10.堆的遍历…

Linux中sudo命令的添加和操作

使用 sudo分配权限 (1)修改/etc/sudoers 文件分配文件 # chmod 740 /etc/sudoers # vi /etc/sudoers 找到这行:root ALL(ALL) ALL, 在这行下面添加 xxx ALL(ALL) ALL (这里的xxx就是你的普通用户,而ruice就是我的普通用户 ) 编…

nginx部署多个项目

前言 实现在一台服务器上使用nginx部署多个项目的方法 查看并修改nginx安装的默认配置文件 在 Linux 操作系统中,Nginx 在编译安装时默认的配置文件路径是 /usr/local/nginx/conf/nginx.conf。 如果是通过发行版的包管理器安装,则默认的配置文件路径可能…

Cesium加载海量点数据

目录 项目地址实现效果实现方法 项目地址 https://github.com/zhengjie9510/webgis-demo 实现效果 实现方法 const pointCollection viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection({ blendOption: Cesium.BlendOption.OPAQUE })); for (let longitude …

dToF 和iToF傻傻分不清楚? pmd flexx2 见你所不能见

在现下数字化越来越成熟的时代,「3D感知」无疑在生活中成为了一种基础、甚至必须的需求:从人手至少一台的智能手机,到居家生活常见的扫地机器人,再到高科技或医疗产业会使用的无人机或工业机器人,如今高度科技化和便捷的世界,处处都需要比肉眼更加强大的立体视角来进行可…

如何搭建Linux环境

W...Y的主页 😊 代码仓库分享 💕 当我们想要搭建一个Linux系统,我们应该怎么使用呢? 今天我就带领大家搭建Linux系统!!! 目录 Linux环境安装 双系统(不推荐) poww…

计算机毕设 图像识别-人脸识别与疲劳检测 - python opencv

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 🔥 这两年开始毕业设计和毕业…

14:00面试,14:06就出来了,问的问题过于变态了。。。

从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到5月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…

【NAD NADPH; FMN FAD ; NMN -化学】

NAD Nicotinamide adenine dinucleotide nicotinamide 烟酰胺 NAD NADPH 烟酰胺腺嘌呤二核苷酸 nucleosidase Nicotinamide adenine dinucleotide NMN(烟酰胺单核苷酸)简介 NMN全名 nicotinamide mononucleotide,即 烟酰胺单…

【全国科普日,共筑眼健康】景远眼科科普志愿者服务队在行动

今年是第21个全国科普日,为深入贯彻落实新时代中国特色社会主义思想,针对不同群体的需求,践行科普为民,共创美好生活,9月14日至9月24日期间,景远眼科科普志愿者服务队把丰富多样的内容、常有常新的活动带到…

IP归属地应用的几个主要特点

作为一款优秀的IP地址定位工具,主题IP归属地的应用无疑是最好的选择之一。该应用可以将您需要查询的IP地址快速定位到所在的具体物理位置,并提供详细的地址和地图信息。接下来,让我们一起来看一看IP归属地应用的几个主要特点: 1. …

Python:求求按规范写我

B站|公众号:啥都会一点的研究生 写在前面 代码被阅读的次数远多于编写的次数 我们可能花费很多时间来编写一段代码,一旦完成后大概率就再不会重新写它。当这段代码不仅是自己用时,就得注意了,每次自己或其他人浏览,需…

2023.9.23(对这一年过去几个月的总结)

这个时间点杭州正在开亚运会,周六,大周,难得的大周,早上在公司健身房跑完步,就来工位看书了。 反思一下: 技术: 今年在技术学习上的目标,达成率是在太低,但看文章输出来…

tcp/ip协议2实现的插图,数据结构

(1)以上是插图第2章和3章 的 mbuf 与 ifnet 与 ifaddr 与 le_softc 与 sockaddr_dl结构体 谢谢

生信技巧 | GNU 并行操作

简介 有些分析需要很长时间,因为它在单个处理器上运行并且有大量数据需要处理。如果数据可以分成块并单独处理,那么问题就被认为是可并行化的。 数据并行情况 当文件的每一行都可以单独处理时 基因组的每条染色体都可以单独处理 组件的每个脚手架都可以单…

安全学习_开发相关_JavaEE过滤器监听器简单了解

文章目录 Web应用运行流程图 JavaEE-过滤器-Filter过滤器概述&作用过滤器相关安全测试场景 JavaEE-监听器-Listener监听器作用:监听器相关安全测试场景 过滤器和监听器,主要对安全测试有影响的是过滤器,监听器只是在对代码进行逻辑分析时…