別的不說逛球,直接上代碼
主要邏輯:
通過jmeter 運行后生成的jtl(output=xml)格式的結(jié)果谒出,通過python腳本轉(zhuǎn)html報告痹籍。(output=csv格式的jmeter -o 自帶的可以生成)
準備python3環(huán)境+python+allure
vim JtlToReportHTML.py
# -*- coding: utf-8 -*-
# @Time : 2022/4/11 下午6:06
# @Author : sleeli
# @File : JtlToReportHTML.py
# @Software: PyCharm
# -*- coding: utf-8 -*-
# @Time : 2022/4/11 4:29 下午
import xml.etree.cElementTree as ET
import json, os, uuid
import sys
# xmlObject xml工程
# checkString 這個其實是固定值 httpSample氓仲,只不過后面想要獲取其他結(jié)構(gòu)參數(shù)化
# num 當(dāng)時想嵌套多層朗恳,后來發(fā)現(xiàn)allure只三層結(jié)構(gòu),其實這個也沒啥用
# result 傳遞解析的xml
# demoFile 生成的pytes文件
# featureIndex 用來排序參數(shù)用例蔚叨,按照jmeter中的樹結(jié)果
# storyIndex 同上床蜘,是第二層級的排序
def checkChildren(xmlObject, checkString, num, result, demoFile, featureIndex, storyIndex):
for children in 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 httpSampleChildren in children:
result[httpSampleChildren.tag] = httpSampleChildren.text
if httpSampleChildren.tag == 'assertionResult':
for assertionResultChildren in 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(\'''請求數(shù)據(jù):{queryString}\'''):
print(\'''請求數(shù)據(jù):{queryString}\''')
with allure.step(\'''接口返回:{responseData}\'''):
print(\'''接口返回:{responseData}\''')
with allure.step(\'''斷言結(jié)果:{failureMessage}\'''):
print(\'''斷言結(jié)果:{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__':
# 通過命令行來執(zhí)行 ,例如python3 JtlToReportHTML.py test.jtl test_demo.py report
commonndLines = sys.argv
print(commonndLines)
with open(commonndLines[2], "w") as demo:
demo.write('''
# -*- coding: utf-8 -*-
import allure
''')
report_resource = commonndLines[3]+"/resource"
report_html = commonndLines[3] + "/html"
tree = ET.parse(commonndLines[1])
root = tree.getroot()
checkChildren(root, "httpSample", 1, {}, commonndLines[2], 1, 1)
pyString = 'pytest --capture=no ' + commonndLines[2] + ' --alluredir ' + report_resource
os.system(pyString)
alSring = "allure generate " + report_resource + " -o " + report_html + " --clean"
os.system(alSring)
通過命令行來執(zhí)行 蔑水,例如
# 會自動創(chuàng)建報告目錄report2
python3 JtlToReportHTML.py test.jtl test_demo.py report2
報告目錄下有有資源和文檔邢锯,如下(我是在report2目錄下生成的報告)
image.png
然后啟動谷歌瀏覽器的本地模式(我的mac,其他系統(tǒng)的自己百度吧搀别,關(guān)鍵字搜索瀏覽器本地跨域 )
open -n /Applications/Google\ Chrome.app/ --args --disable-web-security --user-data-dir=MyChromeDevUserData
最后將report/html/index.html拖到瀏覽器打開查看效果:(注意瀏覽器需要完全退出后在開本地模式丹擎,否則不生效)
image.png
htmlreport.gif
htmlreport2.gif