自动化工具 Python 调 Jmeter 执行参数化 jmx 脚本
烦透了jmeter输入如下鬼命令:
Jmeter -n -t {tmpjmxfile} -l {csvfilename} -e -o {htmlreportpath}
尤其是{htmlreportpath}这个文件夹路径,没有这个文件夹又不会自动创建,有的话又必须为空。经常要给文件夹、文件命名,而且命名又没什么规范,乱七八糟的。
于是想着,即便是用python帮我创建文件夹,帮我生成命令,也是好的。
精益求精,做着做着,就会想着,干脆把命令也给执行了,于是就有这样的产出。
使用场景:
1.需要不断的运行性能测试脚本,摸底,取数。 如线程数、循环次数。
2.需要等待较长时间的
执行此脚本的条件是,在一个目录下,只能有一个jmx后缀文件。当然可以有参数化文件,拷贝execjmeter.py和runafter.py文件到该目录下。简单例子如下:
话不多说,直接来段代码,代码仍需不断改进:
python版本=3.6.1,这段代码命名为execjmeter.py
#coding=utf-8 import os from os.path import join import re import subprocess import time from string import Template currpath = os.path.dirname(os.path.realpath(__file__)) JMETER_Home = r'''"D:\Program Files\apache-jmeter\bin\jmeter.bat"''' origin_jmxfile = replaced_jmxfile = '' def before_check(): global origin_jmxfile count_jmxfile = 0 for root, dirs, files in os.walk(currpath): for name in files: if '-P.jmx' in name: os.remove(join(root, name)) if '-P.jmx' not in name and '.jmx' in name and 'XL' not in name: count_jmxfile = count_jmxfile + 1 origin_jmxfile = join(root, name) if count_jmxfile != 1 and origin_jmxfile: print('为了更智能地执行jmx文件,请确保有且仅有一个有效的jmx文件!') return False else: return True def create_para_jmxfile(): global origin_jmxfile, replaced_jmxfile jmx_str = '' with open(origin_jmxfile, "r", encoding="utf-8") as file: jmx_str = file.read() patten = '<stringProp name="LoopController.loops">(.*?)</stringProp>' replace_str = '<stringProp name="LoopController.loops">$loops</stringProp>' jmx_str = re.sub(patten, replace_str, jmx_str) patten = '<stringProp name="ThreadGroup.num_threads">(.*?)</stringProp>' replace_str = '<stringProp name="ThreadGroup.num_threads">$num_threads</stringProp>' jmx_str = re.sub(patten, replace_str, jmx_str) replaced_jmxfile = origin_jmxfile.replace('.jmx', '-P.jmx') with open(replaced_jmxfile, "w+", encoding="utf-8") as file: file.writelines(jmx_str) def getDateTime(): ''' 获取当前日期时间,格式'20150708085159' ''' return time.strftime(r'%Y%m%d%H%M%S', time.localtime(time.time())) def execcmd(command): print(f"command={command}") output = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, universal_newlines=True) stderrinfo, stdoutinfo = output.communicate() print(f"stderrinfo={stderrinfo}") print(f"stdoutinfo={stdoutinfo}") print(f"returncode={output.returncode}") def execjmxs(Num_Threads, Loops): tmpstr = '' with open(replaced_jmxfile, "r", encoding="utf-8") as file: tmpstr = Template(file.read()).safe_substitute( num_threads=Num_Threads, loops=Loops) now = getDateTime() tmpjmxfile = currpath + f'\{now}-T{Num_Threads}XL{Loops}.jmx' with open(tmpjmxfile, "w+", encoding="utf-8") as file:![](/uploads/photo/2018/66ee114e-365a-4742-825c-f6f68a49926d.png!large) file.writelines(tmpstr) csvfilename = currpath + f"\{now}-result.csv" htmlreportpath = currpath + f"\{now}-htmlreport" if not os.path.exists(htmlreportpath): os.makedirs(htmlreportpath) execjmxouthtml = f"cmd.exe /c {JMETER_Home} -n -t {tmpjmxfile} -l {csvfilename} -e -o {htmlreportpath}" execcmd(execjmxouthtml) if before_check(): create_para_jmxfile() jobs = [dict(Num_Threads=(x+1), Loops=1) for x in range(10)] [execjmxs(x["Num_Threads"], x["Loops"]) for x in jobs]