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

在平时用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_resultfor 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, Noneif 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 Falseelse: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.hqwc.cn/news/194949.html

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

相关文章

AVL树实现

目录 ​编辑 一,AVL树的概念 二,实现AVL树(部分) 1.AVL树的节点 2.AVL数的插入 1.当根节点为nullptr时要执行如下代码: 2.当根节点不为nullptr时 1.当parent的_bf变为0时,parent之前的_bf的大小就是…

前端面试:如何实现并发请求数量控制?

题目:实现一个并发请求函数concurrencyRequest(urls, maxNum) 要求如下: 要求最大并发数 maxNum;每当有一个请求返回,就留下一个空位,可以增加新的请求;所有请求完成后,结果按照 urls 里面的顺序依次打出;…

C++初阶-内存管理

内存管理 一、C/C内存分布二、C语言中动态内存管理方式:malloc/calloc/realloc/free三、C内存管理方式new/delete操作内置类型new和delete操作自定义类型 四、operator new与operator delete函数operator new与operator delete函数 五、new和delete的实现原理内置类…

论文-分布式-拜占庭将军问题

目录 0-前言 1-导引 2-不可能性 3将军(1叛徒)问题不存在解/不能达成共识 少于3m1个将军(有m个叛徒)不存在解/不能达成共识 精确一致性与近似一致性是同等困难的 3-使用口头消息的解 “口头消息”的含义 OM(m)算法的步骤 OM(m)算法的正确性推导 4-使用签名消息情况下…

054-第三代软件开发-信号槽

第三代软件开发-信号槽 文章目录 第三代软件开发-信号槽项目介绍信号槽实现原理与MFC消息映射机制区别Qt信号槽机制的优缺点 关键字: Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QML&#x…

内容运营策略:个性化推荐

一、推荐系统流程 典型的推荐系统包括3个部分,即召回层( Recall )、排序层( Rank )和重排层( ReRank )。 1.召回层( Recall ) 召回层主要是从全量库中首先获取用户可能感兴趣的候选集,是推荐系…

Pytest自动化测试框架:mark用法---测试用例分组执行

pytest中的mark: mark主要用于在测试用例/测试类中给用例打标记(只能使用已注册的标记名),实现测试分组功能,并能和其它插件配合设置测试方法执行顺序等。 如下图,现在需要只执行红色部分的测试方法,其它方法不执行&am…

pytest测试框架介绍(1)

又来每天进步一点点啦~~~ 一、Pytest介绍: pytest 是一个非常成熟的全功能的Python测试框架; pytest 简单、灵活、易上手; 支持参数化 能够支持简单的单元测试和复杂的功能测试,可以做接口自动化测试(pytestrequests&…

谈谈一个IT杂家的职业生涯规划,你的护城河被AI 攻破了么?

文章大纲 未来AI领域的专家是深度学习老中医数据为什么不断的在变化?炼金术(Alchemy)AI“老中医”的经验难以复制 AIGC 还未能克服的难点:忽然的惊喜与价值观对齐失控既是智能获得突破的重要原因,又是智能突破所不可避免的伴生结果大模型在泛…

Google Earth Engine(GEE)操作

地理信息网站 Eatrth Explorer操作界面 在研究中,我们常需要遥感数据。在下面的网站中,可以得到遥感数据。 EarthExplorer (usgs.gov)https://earthexplorer.usgs.gov/登陆网站: 通常,在Additional Criteria中,可以…

SpringBoot——入门及原理

SpringBoot用来简化Spring应用开发,约定大于配置,去繁从简,是由Pivotal团队提供的全新框架。其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置(有特殊需求可以添加自己的配置覆盖默认配…

用户增长模型:3A3R策略模型

一、概述 A - A - A - R - R - R 增长模型,即3A3R策略模型,由海盗模型演变而来,是目前使用最多、适用范围最广的增长策略模型。原始的海盗模型由 Acquisition (获客)、 Activation (活跃)、 Re…