性能工具之Jmeter腳本python啟動
- 2019 年 12 月 24 日
- 筆記
背景
上一節是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 :備註信息,描述該計劃的目的
Action to be taken after a Sampler error
假如請求失敗後,接下來執行什麼動作
- continue 繼續執行接下來的操作
- start Next ThreadLoop 執行下一個線程循環
- Stop Thead 停止該該線程,不在執行該線程的任何操作
- Stop Test 等待該線程的採樣結束後,結束整個測試,不會立即停止
- Stop TestNow 停止整個測試計劃
Thread Properites :線程屬性
- 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 中看到。
specify thread lifetime: 設置執行時間
- Duration(seconnds): 請求的執行時間,它與(Loop Count 的 Infinite)配合使用
- Startup delay(seconds):延遲時間,工作中很少用。
python啟動Jmeter腳本
python基礎知識複習
- 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腳本
腳本參考代碼
# -*- coding: utf-8 -*- # @Time : 2019/12/11 22:07 # @Author : liwen406 # @Email : Jmeter啟動腳本 # @File : startJmeter.py import os, sys def jmeterNumber(caseName, num_threads, ramp_time, duration, remark, hostIps='127.0.0.1'): ''' :param caseName: 腳本名字 :param num_threads: 線程數 :param ramp_time: 控制線程步長 :param duration: 執行時間 :param remark: 標誌 :param hostIps: 負載參數 :return: 啟動JMeter成功 ''' if caseName is None: return "測試用例為空" if num_threads is None: return "虛擬並發數為空" if ramp_time is None: return "測試步驟為空" if duration is None: return "執行時間為空" # 執行腳本名字 runJmeterFile = '%s_%s_%s_%s_%s' % (caseName, num_threads, ramp_time, duration, remark) print("執行名字腳本:%s" % runJmeterFile) thisdir = os.getcwd() # 原始腳本 newdir = os.path.join(thisdir, "testscript", caseName + ".jmx") print("當前腳本路徑: %s" % newdir) if not os.path.exists(newdir): print('腳本不存在!請檢查腳本') return False # 保存測試結果路徑 resultFile = os.path.join(thisdir, 'result', runJmeterFile) print("腳本執行路徑: ", resultFile) # 判斷結果路徑是否存在 if not os.path.exists(resultFile): os.makedirs(resultFile) lines = open(newdir, encoding="utf-8").readlines() fp = open(os.path.join(thisdir, "result", resultFile, runJmeterFile) + '.jmx', 'w') # 打開你要寫得文件 for s in lines: fp.write(s.replace('num_threads">1</stringProp>', 'num_threads">%s</stringProp>' % num_threads) # 替換並發數 .replace('ramp_time">1</stringProp>', 'ramp_time">%s</stringProp>' % ramp_time) # 替換步長 .replace('scheduler">false</boolProp>', 'scheduler">true</boolProp>') # 勾選通過時間判斷結束 .replace('duration"></stringProp>', 'duration">%s</stringProp>' % duration) # 替換執行時間 .replace('name="LoopController.loops">1</stringProp>', 'name="LoopController.loops">-1</stringProp>')) # 勾選通過時間判斷結束 fp.close() os.chdir(resultFile) print("當前路徑: ", os.getcwd()) # 檢查環境變量 if isEvn(): # 判斷分佈式執行方式 if len(hostIps.split(",")) > 2: # 根據自己需求添加執行類型 Rcmd = 'jmeter -n -t %s.jmx -R %s -l %s.jtl -j %s.log' % ( runJmeterFile, hostIps, runJmeterFile, runJmeterFile) # Rcmd = 'jmeter -n -t %s.jmx -R %s -l %s.jtl -j %s.log -e -o %s' % (runJmeterFile, hostIps, runJmeterFile, runJmeterFile, runJmeterFile) print('執行命令:%s' % Rcmd) # os.system(Rcmd) else: # 不生成html報告 # cmd = 'jmeter -n -t %s.jmx -l %s.jtl -j %s.log' % (runJmeterFile, runJmeterFile, runJmeterFile, runJmeterFile) # 自動生成html報表 cmd = 'jmeter -n -t %s.jmx -l %s.jtl -j %s.log -e -o %s' % ( runJmeterFile, runJmeterFile, runJmeterFile, runJmeterFile) print('執行命令:%s' % cmd) os.system(cmd) def isEvn(): ''' 檢查環境變量 :return: True/Fals ''' cmd = 'jmeter -v' lin = os.popen(cmd) for i in lin: if 'The Apache Software Foundation' in i: print("Jmeter環境變量配置成功") return True else: print("Jmeter環境變量配置失敗") return False if __name__ == '__main__': # 分佈式ip寫法,多個使用逗號隔開 hostIps = '127.0.0.1' if len(sys.argv[1:]) == 5: print('參數個數為:', len(sys.argv), '個參數。') print('可用參數列表:', str(sys.argv[1:])) param = sys.argv[1:] print("腳本名字: %s,並發數: %s,步長: %s,執行時間: %s,備註: %s" % (param[0], param[1], param[2], param[3], param[4])) jmeterNumber(param[0], param[1], param[2], param[3], param[4], hostIps) else: print("參數不對") pass
上面腳本注釋的很清楚,相信大家一看就知道怎麼修改參數,上面腳本可以個參考,大家可以根據實際情況修改參數,達到自己預期結果。
注意
使用python執行Jmeter腳本需要與Jmeter腳本有約定,這樣才能通過python腳本去執行咱們的Jmeter測試腳本。

xml中

腳本中:

執行結果

Hmtml報表

傳參說明:
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啟動
做性能測試執行腳本是個體力活,怎麼節約體力活的時間,可以通過腳本語言把重複的工作量替換,這樣咱們可以把更多時間用到刀刃上。
看累了讀一讀咱們中學的古文:
《勸學》
積土成山,風雨興焉;積水成淵,蛟龍生焉;積善成德,而神明自得,聖心備焉。故不積跬步,無以至千里;不積小流,無以成江海。騏驥一躍,不能十步;駑馬十駕,功在不舍。鍥而舍之,朽木不折;鍥而不捨,金石可鏤。蚓無爪牙之利,筋骨之強,上食埃土,下飲黃泉,用心一也。蟹六跪而二螯,非蛇鱔之穴無可寄託者,用心躁也。


