性能工具之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啟動

做性能測試執行腳本是個體力活,怎麼節約體力活的時間,可以通過腳本語言把重複的工作量替換,這樣咱們可以把更多時間用到刀刃上。

看累了讀一讀咱們中學的古文:

《勸學》

積土成山,風雨興焉;積水成淵,蛟龍生焉;積善成德,而神明自得,聖心備焉。故不積跬步,無以至千里;不積小流,無以成江海。騏驥一躍,不能十步;駑馬十駕,功在不舍。鍥而舍之,朽木不折;鍥而不捨,金石可鏤。蚓無爪牙之利,筋骨之強,上食埃土,下飲黃泉,用心一也。蟹六跪而二螯,非蛇鱔之穴無可寄託者,用心躁也。