美文网首页自动化测试
Jmeter输出报告转allure2

Jmeter输出报告转allure2

作者: MMMJoker | 来源:发表于2020-12-02 19:13 被阅读0次

    最近发现公司很多是jmeter进行的自动化测试,存在的问题:原生报告巨丑无比,并且还没有那么友好的展示详情。

    话不多说,开搞。

    首先是jmeter配置的调整,需要拿到整个请求的详情

    1、找到jmeter bin目录下的jmeter.properties修改配置如下

    2、找到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

    3、通过/u01/jmeter/apache-jmeter-5.3/bin/jmeter.sh -n -t xxx.jmx -l result.xml -j test.log 输出报告

    这个时候就会发现输出的xml报告包含了用例的层级和详情信息

    <httpSample t="1" lt="1" ts="1450684950333" s="true" lb="app.testdelay" rc="200" rm="OK" tn="appdelay-3000g3m 1-1" dt="" by="2265"/>

    t表示从请求开始到响应结束的时间

    lt表示整个的空闲时间

    ts表示访问的时刻

    s表示返回的结果true表示成功,false表示失败

    lb表示标题

    rc表示返回的响应码

    rm表示响应信息

    tn表示线程的名字“1-138”表示第1个线程组的第138个线程。

    dt表示响应的文件类型

    by表示请求和响应的字节数

    到这里差不多完成一半了,有这个xml,我把它解析成自己想要的pytest allure不就行了

    4、把xml报告处理成pytest,python3代码如下

            #通过命令行来执行 ,例如python3 dealReportXml.py result.xml test_demo.py report/resource

    # -*- coding: utf-8 -*-

    # @Time    : 2020/11/30 4:29 下午

    import xml.etree.cElementTreeas ET

    import json,os,uuid

    import sys

    # xmlObject xml工程

    # checkString 这个其实是固定值 httpSample,只不过后面想要获取其他结构参数化

    # num 当时想嵌套多层,后来发现allure只三层结构,其实这个也没啥用

    # result 传递解析的xml

    # demoFile 生成的pytes文件

    # featureIndex 用来排序参数用例,按照jmeter中的树结果

    # storyIndex 同上,是第二层级的排序

    def checkChildren(xmlObject, checkString, num, result, demoFile, featureIndex, storyIndex):

        for childrenin xmlObject:

            try:

                if num == 1 and children.attrib['sby'] != "0":

                    featureIndexStr='#'+str(featureIndex)+" " if featureIndex >= 10 else '#0'+str(featureIndex)+" "

                    result["feature"] = featureIndexStr+children.attrib['lb']

                    featureIndex += 1

                if num >= 2 and children.tag== "sample":

                    storyIndexStr= '#' + str(storyIndex) + " " if storyIndex >= 10 else '#0' + str(

                        storyIndex) + " "

                    result["story"] = storyIndexStr+children.attrib['lb']

                    storyIndex += 1

            except:

                pass

            if children.tag== checkString:

                result['case_name'] = children.attrib['lb']

                for httpSampleChildrenin children:

                    result[httpSampleChildren.tag] = httpSampleChildren.text

    if httpSampleChildren.tag== 'assertionResult':

                        for assertionResultChildrenin httpSampleChildren:

                            result[assertionResultChildren.tag] = assertionResultChildren.text

    feature= result['feature'] if "feature" in result else None

                story= result['story'] if 'story' in result else None

                case_name= result['case_name'] if 'case_name' in result else None

                URL= result['java.net.URL'] if 'java.net.URL' in result else None

                method= result['method'] if 'method' in result else None

                requestHeader= result['requestHeader'] if 'requestHeader' in result else None

                queryString= result['queryString'] if 'queryString' in result else None

                responseData= result['responseData'] if 'responseData' in result else None

                failureMessage= result['failureMessage'] if 'failureMessage' in result else None

                failure= result['failure'] if 'failure' in result else "false"

                print(feature,story,case_name,failureMessage,URL)

                storyString= "@allure.story('"+result['story']+"')  # 二级目录" if 'story' in result else ''

                pyString= '''

    @allure.feature('{feature}')  # 一级目录{story}

    @allure.title("{case_name}")

    def test_allure_report_{num}():

        with allure.step('请求url:{URL}'):

            print('请求url:{URL}')

        with allure.step('请求方法:{method}' ):

            print('请求方法:{method}' )

        with allure.step('请求头:{requestHeader}' ):

            print('请求头:{requestHeader}' )

        with allure.step(\'''请求数据:{queryString}\'''):

            print(\'''请求数据:{queryString}\''')

        with allure.step('接口返回:{responseData}'):

            print('接口返回:{responseData}')

        with allure.step('断言结果:{failureMessage}'):

            print('断言结果:{failureMessage}')

        assert "{failure}" == 'false' '''.format(feature=feature,story=storyString,case_name=case_name,

                                                num=str(uuid.uuid1()).replace('-',''),

                                              URL=URL,method=method, requestHeader=str(requestHeader).replace('\n', '').replace('\r', ''),

                                                queryString=str(json.dumps(queryString)).replace("'","\""),

                                                responseData=str(json.dumps(responseData)).replace("'","\""),

                                              failureMessage=str(failureMessage).replace("'","\""),failure=failure)

                print(pyString)

                with open(demoFile,'a') as c:

                    c.write(pyString)

            else:

                checkChildren(children,checkString,num+1,result,demoFile,featureIndex,storyIndex)

    if __name__== '__main__':

        #通过命令行来执行 ,例如python3 dealReportXml.py result.xml test_demo.py report/resource

        commonndLines= sys.argv

    print(commonndLines)

        with open(commonndLines[2], "w") as demo:

            demo.write('''

    # -*- coding: utf-8 -*-

    import allure

                ''')

        tree= ET.parse(commonndLines[1])

        root= tree.getroot()

        checkChildren(root,"httpSample",1,{},commonndLines[2],1,1)

        pyString= 'pytest --capture=no '+commonndLines[2]+' --alluredir '+commonndLines[3]

        os.system(pyString)

        alSring= "allure generate "+commonndLines[3]+" -o report/html --clean"

        os.system(alSring)

    5、打开生成的报告

    细心的你会发现,这里面的时间是错误的,别急,我们来处理一下。

    回头看看jmeter报告中的协议

    t表示从请求开始到响应结束的时间

    lt表示整个的空闲时间

    ts表示访问的时刻

    s表示返回的结果true表示成功,false表示失败

    lb表示标题

    rc表示返回的响应码

    rm表示响应信息

    tn表示线程的名字“1-138”表示第1个线程组的第138个线程。

    dt表示响应的文件类型

    by表示请求和响应的字节数

    只要我们把对应的时间替换报告中对应的时间即可

    6、优化 把jmeter的实际执行时间匹配进去,最终版本,如下

    直接执行命令

     python3 dealReportXml.py result.xml test_demo.py report/resource

    allure generate report/resource -o report/html --clean

    完整代码如下

    # -*- coding: utf-8 -*-

    # @Time    : 2020/11/30 4:29 下午

    import xml.etree.cElementTreeas ET

    import json,os,uuid

    import sys

    from osimport listdir

    from os.pathimport isfile, join

    # xmlObject xml工程

    # checkString 这个其实是固定值 httpSample,只不过后面想要获取其他结构参数化

    # num 当时想嵌套多层,后来发现allure只三层结构,其实这个也没啥用

    # result 传递解析的xml

    # demoFile 生成的pytes文件

    # featureIndex 用来排序参数用例,按照jmeter中的树结果

    # storyIndex 同上,是第二层级的排序

    # timeChekout 用来替换allure报告中的时间为jmeter报告时间

    def checkChildren(xmlObject, checkString, num, result, demoFile, featureIndex, storyIndex,timeChekout):

        for childrenin xmlObject:

            try:

                if num == 1 and children.attrib['sby'] != "0":

                    featureIndexStr='#'+str(featureIndex)+" " if featureIndex >= 10 else '#0'+str(featureIndex)+" "

                    result["feature"] = featureIndexStr+children.attrib['lb']

                    featureIndex += 1

                if num >= 2 and children.tag== "sample":

                    storyIndexStr= '#' + str(storyIndex) + " " if storyIndex >= 10 else '#0' + str(

                        storyIndex) + " "

                    result["story"] = storyIndexStr+children.attrib['lb']

                    storyIndex += 1

            except:

                pass

            if children.tag== checkString:

                result['caseName'] = children.attrib['lb']

                for httpSampleChildrenin children:

                    if httpSampleChildren.tag== 'assertionResult':

                        assertionResultChildrenTag=[]

                        for assertionResultChildrenin httpSampleChildren:

                            assertionResultChildrenTag.append(assertionResultChildren.tag)

                            result[assertionResultChildren.tag] = assertionResultChildren.text

    if "failureMessage" not in assertionResultChildrenTag:

                            result['failureMessage'] = None

                    else:

                        result[httpSampleChildren.tag] = httpSampleChildren.text

    feature= result['feature'] if "feature" in result else None

                caseName= result['caseName'] if 'caseName' in result else None

                URL= result['java.net.URL'] if 'java.net.URL' in result else None

                method= result['method'] if 'method' in result else None

                requestHeader= result['requestHeader'] if 'requestHeader' in result else None

                queryString= result['queryString'] if 'queryString' in result else None

                responseData= result['responseData'] if 'responseData' in result else None

                failureMessage= result['failureMessage'] if 'failureMessage' in result else None

                failure= result['failure'] if 'failure' in result else "false"

                menthodUuid= str(uuid.uuid1()).replace('-','')

                start= int(children.attrib['ts'])

                stop= int(children.attrib['ts'])+int(children.attrib['t'])

                timeChekout["test_demo#test_allure_report_"+menthodUuid]={"start":start,"stop":stop}

                storyString= "@allure.story('"+result['story']+"')  # 二级目录" if 'story' in result else ''

                pyString= '''

    @allure.feature('{feature}')  # 一级目录{story}

    @allure.title("{caseName}")

    def test_allure_report_{num}():

        with allure.step('请求url:{URL}'):

            print('请求url:{URL}')

        with allure.step('请求方法:{method}' ):

            print('请求方法:{method}' )

        with allure.step('请求头:{requestHeader}' ):

            print('请求头:{requestHeader}' )

        with allure.step(\'''请求数据:{queryString}\'''):

            print(\'''请求数据:{queryString}\''')

        with allure.step('接口返回:{responseData}'):

            print('接口返回:{responseData}')

        with allure.step('断言结果:{failureMessage}'):

            print('断言结果:{failureMessage}')

        assert "{failure}" == 'false' '''.format(feature=feature,story=storyString,caseName=caseName,

                                                num=menthodUuid,URL=URL,method=method, requestHeader=str(requestHeader).replace('\n', '').replace('\r', ''),

                                                queryString=str(json.dumps(queryString)).replace("'","\""),

                                                responseData=str(json.dumps(responseData)).replace("'","\""),

                                                failureMessage=str(failureMessage).replace("'","\""),failure=failure)

                with open(demoFile,'a') as c:

                    c.write(pyString)

            else:

                checkChildren(children,checkString,num+1,result,demoFile,featureIndex,storyIndex,timeChekout)

        return timeChekout

    if __name__== '__main__':

        #通过命令行来执行 ,例如python3 dealReportXml.py result.xml test_demo.py report/resource

        commonndLines= sys.argv

    with open(commonndLines[2], "w") as demo:

            demo.write('''

    # -*- coding: utf-8 -*-

    import allure

                ''')

        tree= ET.parse(commonndLines[1])

        root= tree.getroot()

        realQueryTime= checkChildren(root,"httpSample",1,{},commonndLines[2],1,1,{})

        pyString= 'pytest --capture=no '+commonndLines[2]+' --alluredir '+commonndLines[3]

        os.system(pyString)

        files= [mfor min listdir(commonndLines[3]+"/") if isfile(join(commonndLines[3]+"/", m))]

        for filein files:

            if ".json" in file:

                try:

                    with open(commonndLines[3]+"/" + file, 'r') as f:

                        jsonStr= json.loads(f.read())

                        start= realQueryTime[jsonStr['fullName']]["start"]

                        stop= realQueryTime[jsonStr['fullName']]["stop"]

                        jsonStr['start'] = start

    jsonStr['stop'] = stop

    with open(commonndLines[3]+"/" + file, "w") as m:

                            json.dump(jsonStr, m, indent=2, sort_keys=True, ensure_ascii=False)  # 写为多行

                except:

                    pass


    打开报告看时间和jmeter报告中一样,有没有很爽

    相关文章

      网友评论

        本文标题:Jmeter输出报告转allure2

        本文链接:https://www.haomeiwen.com/subject/hkruwktx.html