背景
上一節是shell指令啟動Jmeter,擔心大家對shell腳本文法不是很熟悉,如果定制自己想要的恐怕不好弄,這次改用python啟動腳本,在改造之前大家先了解下Jmeter線程組相關參數,這樣對大家改造腳本有一定幫助。
python中os、sys、file子產品函數
Jmeter 執行方式【jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]】

Name :Thread Group 線程組的名稱,可以根據項目名稱定義
Comments :備注資訊,描述該計劃的目的
假如請求失敗後,接下來執行什麼動作
continue 繼續執行接下來的操作
start Next ThreadLoop 執行下一個線程循環
Stop Thead 停止該該線程,不在執行該線程的任何操作
Stop Test 等待該線程的采樣結束後,結束整個測試,不會立即停止
Stop TestNow 停止整個測試計劃
Number of Threads(users) :線程數,也就虛拟使用者數
Ramp-uo Period(in seconds) :控制虛拟使用者啟動時間
Loop Count:控制執行次數。Infinite 假如勾選表示無線執行,它主要與後面的 Duration 配合使用
Same user on each iteration : 每次疊代使用相同的使用者
Delay Thread creation until needed 将線程建立延遲到需要的時候
Number of Threads * Loop Count 就是 Sampler 執行的次數,可以在 View Results Tree 中看到。
Duration(seconnds): 請求的執行時間,它與(Loop Count 的 Infinite)配合使用
Startup delay(seconds):延遲時間,工作中很少用。
python啟動Jmeter腳本
os.sep: 取代作業系統特定的路徑分隔符
os.name: 訓示你正在使用的工作平台。
os.getcwd: 得到目前工作目錄,即目前python腳本工作的目錄路徑。
os.getenv()和os.putenv: 分别用來讀取和設定環境變量
os.listdir(): 傳回指定目錄下的所有檔案和目錄名
os.remove(file): 删除一個檔案
os.stat(file): 獲得檔案屬性
os.chmod(file): 修改檔案權限和時間戳
os.mkdir(name): 建立目錄
os.rmdir(name): 删除目錄
os.removedirs: 删除多個目錄
os.system(): 運作shell指令
os.exit(): 終止目前程序
os.linesep: 給出目前平台的行終止符。
os.path.split(): 傳回一個路徑的目錄名和檔案名
os.path.isfile()和os.path.isdir()分别檢驗給出的路徑是一個目錄還是檔案
os.path.existe(): 檢驗給出的路徑是否真的存在
os.listdir(dirname): 列出dirname下的目錄和檔案
os.getcwd(): 獲得目前工作目錄
os.curdir: 傳回目前目錄('.')
os.chdir(dirname): 改變工作目錄到dirname
os.path.isdir(name): 判斷name是不是目錄,不是目錄就傳回false
os.path.isfile(name): 判斷name這個檔案是否存在,不存在傳回false
os.path.exists(name): 判斷是否存在檔案或目錄name
os.path.getsize(name): 獲得檔案大小,如果name是目錄傳回0L
os.path.abspath(name): 獲得絕對路徑
os.path.isabs(): 判斷是否為絕對路徑
os.path.normpath(path): 規範path字元串形式
os.path.split(name): 分割檔案名與目錄
os.path.splitext(): 分離檔案名和擴充名
os.path.join(path,name): 連接配接目錄與檔案名或目錄
os.path.basename(path): 傳回檔案名
os.path.dirname(path): 傳回檔案路徑
with open( 檔案名, '操作類型' ) as f: f.read()
open(檔案名,操作類型) f.readlines()
rand()
readline()
readlines()
seek
....等等
有上面基礎知識,現在開始分析python啟動Jmeter腳本
擷取腳本路徑,通過指令打開檔案
替換jmeter腳本中的線程數,步長、執行時間内容,并且重命名腳本
通過指令行執行jmeter腳本
腳本參考代碼
<code># -*- coding: utf-8 -*-</code>
<code># @Time : 2019/12/11 22:07</code>
<code># @Author : liwen406</code>
<code># @Email : Jmeter啟動腳本</code>
<code># @File : startJmeter.py</code>
<code>import os, sys</code>
<code>def jmeterNumber(caseName, num_threads, ramp_time, duration, remark, hostIps='127.0.0.1'):</code>
<code>'''</code>
<code>:param caseName: 腳本名字</code>
<code>:param num_threads: 線程數</code>
<code>:param ramp_time: 控制線程步長</code>
<code>:param duration: 執行時間</code>
<code>:param remark: 标志</code>
<code>:param hostIps: 負載參數</code>
<code>:return: 啟動JMeter成功</code>
<code>if caseName is None:</code>
<code>return "測試用例為空"</code>
<code>if num_threads is None:</code>
<code>return "虛拟并發數為空"</code>
<code>if ramp_time is None:</code>
<code>return "測試步驟為空"</code>
<code>if duration is None:</code>
<code>return "執行時間為空"</code>
<code># 執行腳本名字</code>
<code>runJmeterFile = '%s_%s_%s_%s_%s' % (caseName, num_threads, ramp_time, duration, remark)</code>
<code>print("執行名字腳本:%s" % runJmeterFile)</code>
<code>thisdir = os.getcwd()</code>
<code># 原始腳本</code>
<code>newdir = os.path.join(thisdir, "testscript", caseName + ".jmx")</code>
<code>print("目前腳本路徑: %s" % newdir)</code>
<code>if not os.path.exists(newdir):</code>
<code>print('腳本不存在!請檢查腳本')</code>
<code>return False</code>
<code># 儲存測試結果路徑</code>
<code>resultFile = os.path.join(thisdir, 'result', runJmeterFile)</code>
<code>print("腳本執行路徑: ", resultFile)</code>
<code># 判斷結果路徑是否存在</code>
<code>if not os.path.exists(resultFile):</code>
<code>os.makedirs(resultFile)</code>
<code>lines = open(newdir, encoding="utf-8").readlines()</code>
<code>fp = open(os.path.join(thisdir, "result", resultFile, runJmeterFile) + '.jmx', 'w') # 打開你要寫得檔案</code>
<code>for s in lines:</code>
<code>fp.write(s.replace('num_threads">1</stringProp>', 'num_threads">%s</stringProp>' % num_threads) # 替換并發數</code>
<code>.replace('ramp_time">1</stringProp>', 'ramp_time">%s</stringProp>' % ramp_time) # 替換步長</code>
<code>.replace('scheduler">false</boolProp>', 'scheduler">true</boolProp>') # 勾選通過時間判斷結束</code>
<code>.replace('duration"></stringProp>', 'duration">%s</stringProp>' % duration) # 替換執行時間</code>
<code>.replace('name="LoopController.loops">1</stringProp>',</code>
<code>'name="LoopController.loops">-1</stringProp>')) # 勾選通過時間判斷結束</code>
<code>fp.close()</code>
<code>os.chdir(resultFile)</code>
<code>print("目前路徑: ", os.getcwd())</code>
<code># 檢查環境變量</code>
<code>if isEvn():</code>
<code># 判斷分布式執行方式</code>
<code>if len(hostIps.split(",")) > 2:</code>
<code># 根據自己需求添加執行類型</code>
<code>Rcmd = 'jmeter -n -t %s.jmx -R %s -l %s.jtl -j %s.log' % (</code>
<code>runJmeterFile, hostIps, runJmeterFile, runJmeterFile)</code>
<code># Rcmd = 'jmeter -n -t %s.jmx -R %s -l %s.jtl -j %s.log -e -o %s' % (runJmeterFile, hostIps, runJmeterFile, runJmeterFile, runJmeterFile)</code>
<code>print('執行指令:%s' % Rcmd)</code>
<code># os.system(Rcmd)</code>
<code>else:</code>
<code># 不生成html報告</code>
<code># cmd = 'jmeter -n -t %s.jmx -l %s.jtl -j %s.log' % (runJmeterFile, runJmeterFile, runJmeterFile, runJmeterFile)</code>
<code># 自動生成html報表</code>
<code>cmd = 'jmeter -n -t %s.jmx -l %s.jtl -j %s.log -e -o %s' % (</code>
<code>runJmeterFile, runJmeterFile, runJmeterFile, runJmeterFile)</code>
<code>print('執行指令:%s' % cmd)</code>
<code>os.system(cmd)</code>
<code>def isEvn():</code>
<code>檢查環境變量</code>
<code>:return: True/Fals</code>
<code>cmd = 'jmeter -v'</code>
<code>lin = os.popen(cmd)</code>
<code>for i in lin:</code>
<code>if 'The Apache Software Foundation' in i:</code>
<code>print("Jmeter環境變量配置成功")</code>
<code>return True</code>
<code>print("Jmeter環境變量配置失敗")</code>
<code>if __name__ == '__main__':</code>
<code># 分布式ip寫法,多個使用逗号隔開</code>
<code>hostIps = '127.0.0.1'</code>
<code>if len(sys.argv[1:]) == 5:</code>
<code>print('參數個數為:', len(sys.argv), '個參數。')</code>
<code>print('可用參數清單:', str(sys.argv[1:]))</code>
<code>param = sys.argv[1:]</code>
<code>print("腳本名字: %s,并發數: %s,步長: %s,執行時間: %s,備注: %s" % (param[0], param[1], param[2], param[3], param[4]))</code>
<code>jmeterNumber(param[0], param[1], param[2], param[3], param[4], hostIps)</code>
<code>print("參數不對")</code>
<code>pass</code>
上面腳本注釋的很清楚,相信大家一看就知道怎麼修改參數,上面腳本可以個參考,大家可以根據實際情況修改參數,達到自己預期結果。
使用python執行Jmeter腳本需要與Jmeter腳本有約定,這樣才能通過python腳本去執行咱們的Jmeter測試腳本。
python startJmeter.py tiaoshi 2 1 30 pythontiaoshi
python表示通過python腳本語言執行
startJmeter.py 表示啟動腳本名字
tiaoshi 表示Jmeter腳本名字
2 表示并發數
1 執行步長
30 表示執行時間
pythontiaoshi 表示備注,友善一個腳本多次執行好分别每次執行的結果
替換前腳本
替換後腳本
目前操作目錄
總結
目前該腳本在 win 環境中行,如果放到Linux中去執行相信應該是可以的,應Linux中也有python環境,不過本次使用的是python3執行,如果再Linux中是python2需要修改相應位置即可執行,如果喜歡shell啟動的可以參考性能工具之Jmeter使用shell啟動
做性能測試執行腳本是個體力活,怎麼節約體力活的時間,可以通過腳本語言把重複的工作量替換,這樣咱們可以把更多時間用到刀刃上。
看累了讀一讀咱們中學的古文:
《勸學》
積土成山,風雨興焉;積水成淵,蛟龍生焉;積善成德,而神明自得,聖心備焉。故不積跬步,無以至千裡;不積小流,無以成江海。骐骥一躍,不能十步;驽馬十駕,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。蚓無爪牙之利,筋骨之強,上食埃土,下飲黃泉,用心一也。蟹六跪而二螯,非蛇鳝之穴無可寄托者,用心躁也。