软件测试|使用allure展示jmeter测试报告

使用allure展示jmeter测试报告 jmeter本身自带的测试报告实在有点差强人意,本文介绍如何通过allure展示测试报告
实现的效果 软件测试|使用allure展示jmeter测试报告
文章图片
软件测试|使用allure展示jmeter测试报告
文章图片

修改jmeter配置文件

修改jmeter bin目录下jmeter.properties

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=https://www.it610.com/article/true # Save ResponseData for failed samples jmeter.save.saveservice.response_data.on_error=false 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=false 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=false jmeter.save.saveservice.idle_time=true

修改jmeter bin目录下user.properties

jmeter.save.saveservice.output_format=xml jmeter.save.saveservice.response_data=https://www.it610.com/article/true jmeter.save.saveservice.samplerData=true jmeter.save.saveservice.requestHeaders=true jmeter.save.saveservice.url=true jmeter.save.saveservice.responseHeaders=true

执行命令
sudo sh jmeter -n -t xx.jmx -l result.xml
可以查看生成的结果文件
如下:
软件测试|使用allure展示jmeter测试报告
文章图片

对生成的结果文件重新进行解析,采用pytest+allure 模式重新对结果文件进行自动化测试 文件解析
从结果文件中我们可以筛选出我们所需要的内容如下
""" t 从请求开始到响应结束的时间 ts 表示访问的时刻: date s 运行的结果 lb 表示标题 rc 返回的响应码 rm 响应信息 tn 线程的名字,这里可以添加自己的配置信息,我这里增加的文件名以及运行环境 assertionResult: 断言信息 responseData/samplerData: 返回数据 queryString: 请求信息 """

接下来我们利用生成的结果文件生成pytest的参数化数据
如下
try: converte_data = https://www.it610.com/article/xmltodict.parse(result_file, encoding='utf-8') result = [] sample_result = converte_data['testResults']['httpSample'] if isinstance( converte_data['testResults']['httpSample'], list) else [converte_data['testResults']['httpSample']] 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 '' # date = datetime.fromtimestamp(data['@ts']/1000).strftime("%Y:%m:%d %H:%M:%S") if '@ts' in data else None status = data['@s'] if '@s' in data else '' title = data['@lb'] if '@lb' in data else '' returm_code = data['@rc'] if '@rc' in data else '' return_message = data['@rm'] if '@rm' in data else '' thread = data['@tn'] if '@tn' in data else '' assertion_result = data['assertionResult'] if 'assertionResult' in data else '' response_data = https://www.it610.com/article/data['responseData']['#text'] if 'responseData' in data and '#text' in data['responseData']\ else '' sampler_data = https://www.it610.com/article/data['samplerData']['#text'] if 'samplerData' in data and '#text' in data['samplerData'] \ else '' request_data = https://www.it610.com/article/data['queryString']['#text'] if 'queryString' in data and '#text' in data[ 'queryString'] else '' request_url = data['java.net.URL'] if 'java.net.URL' in data else '' meta_data = https://www.it610.com/article/(time, date, status, title, returm_code, return_message, thread, assertion_result,response_data , sampler_data, request_data, request_url) #meta_data = (title,assertion_result) result.append(meta_data) return result except Exception as e: print(e)

测试文件结构如下:
class TestTa:@allure.step('接口名称') def title_step(self,title): print(title)@allure.step('请求信息') def request_step(self,request_url, request_data): print(request_url) print(request_data)@allure.step('断言信息') def assert_step(self,assertion_name,assertion_result): assert False@allure.step('文件信息') def file_step(self,thread): print(thread)@allure.step('返回信息') def response_step(self,returm_code, return_message, response_data, sampler_data): if response_data: allure.attach(response_data, name='responseData') if sampler_data: allure.attach(sampler_data, name='wsResponse') print(returm_code, return_message, response_data, sampler_data)def base_step(self,time, date, status, title, returm_code, return_message, thread, assertion, response_data, sampler_data, request_data, request_url): with allure.step('接口信息'): self.title_step(title) self.request_step(request_url, request_data) self.response_step(returm_code, return_message, response_data, sampler_data) self.file_step(thread) if status == 'false': if isinstance(assertion,list): for value in assertion: if 'failureMessage' in value and value['failureMessage'] is not None: self.assert_step(value['name'],value['failureMessage']) assert False elif isinstance(assertion,dict): if 'failureMessage' in assertion and assertion['failureMessage'] is not None: self.assert_step(assertion['name'],assertion['failureMessage']) assert False assert False else: assert True@allure.title("{title}") @allure.feature("xxx") @pytest.mark.parametrize( "time,date,status,title,returm_code,return_message,thread,assertion,response_data,sampler_data,request_data," "request_url", xml_2_data(type=1)) def test_ta(self,time, date, status, title, returm_code, return_message, thread, assertion, response_data, sampler_data, request_data, request_url): self.base_step(time, date, status, title, returm_code, return_message, thread, assertion, response_data, sampler_data, request_data, request_url)

同步执行时间与实际jmeter执行时间相同
def report_edit(): path = os.path.join(Path().get_report_path(),'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)

备份每次的报告及报告生成
now = time.strftime("%Y%m%d%H%M%S") pytest.main(['-s', '-q', CASE_DIR, '--alluredir', os.path.join(RESULT_DIR, 'result-{0}'.format(now))]) shutil.copyfile(os.path.join(RESULT_DIR,'environment.properties'), os.path.join(RESULT_DIR, 'result-{0}'.format(now), 'environment.properties')) shutil.copyfile(os.path.join(RESULT_DIR,'categories.json'), os.path.join(RESULT_DIR, 'result-{0}'.format(now), 'categories.json')) shutil.copytree(REPORT_DIR,os.path.join(CASE_DIR,'report_bak','report-{}'.format(now))) os.system('allure generate {} -o {} --clean'.format (os.path.join(RESULT_DIR, 'result-{}'.format(now)), REPORT_DIR)) #处理报告文件中case时间与实际执行时间保持一致 report_edit()

【软件测试|使用allure展示jmeter测试报告】可以采用nginx或者直接使用Jenkins集成均可以

    推荐阅读