使用allure展示jmeter测试报告

使用allure展示jmeter测试报告

jmeter本身自带的测试报告实在有点差强人意,本文介绍如何通过allure展示测试报告

实现的效果

在这里插入图片描述在这里插入图片描述

修改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=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=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
可以查看生成的结果文件
如下:
在这里插入图片描述

对生成的结果文件重新进行解析,采用pytest+allure 模式重新对结果文件进行自动化测试

文件解析

从结果文件中我们可以筛选出我们所需要的内容如下

"""
t 从请求开始到响应结束的时间
ts 表示访问的时刻: date
s 运行的结果
lb 表示标题
rc 返回的响应码
rm 响应信息
tn 线程的名字,这里可以添加自己的配置信息,我这里增加的文件名以及运行环境
assertionResult: 断言信息
responseData/samplerData: 返回数据
queryString: 请求信息
"""

接下来我们利用生成的结果文件生成pytest的参数化数据
如下

try:
        converte_data = 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 = 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_url = data['java.net.URL'] if 'java.net.URL' in data else ''
            meta_data = (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()

可以采用nginx或者直接使用Jenkins集成均可以

获取项目源码:关注公众号,回复:测试报告
在这里插入图片描述

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值