實現Python壓力測試工具|Python 主題月

NoBugBoy發表於2021-07-13

Python壓力測試工具

寫這個東西的初衷是因為,馬上就要壓力測試,想要寫一個工具並可以根據結果生成圖表,在該專案基礎上可以定製化開發,喜歡或對你有幫助給個start謝謝啦

完整程式碼github地址

用到的技術和依賴包

  1. 多執行緒

  2. requests

  3. pyecharts

配置了兩種發起請求方式(這裡如果數量過多還可以再優化多執行緒迴圈)

  1. 快速請求,將請求池中的請求全部傳送
  2. 慢速請求,在指定的時間內全部傳送完畢
def fast_run(begin, end):
   log.logger.warning("開始index{} 結束index{}".format(begin, end))
   run_start_time = time.time()
   log.logger.info('開始發起快速非同步請求....')
   for request in syncPool[int(begin):int(end)]:
       request.start()
   log.logger.warning("請求消耗時間 {:.2f} 豪秒".format((time.time() - run_start_time) * 1000))
   
def slow_run(begin, end, slowTime):
   log.logger.warning("開始index{} 結束index{}".format(begin, end))
   run_start_time = time.time()
   log.logger.info('開始發起慢速非同步請求....')
   if slowTime == 0:
       fast_run(begin, end)
   else:
       waitTime = round(((slowTime * 1000) / len(syncPool)) / 1000, 3)
       log.logger.info("延遲時間為{}毫秒".format(waitTime * 1000))
       for request in syncPool[int(begin):int(end)]:
           request.start()
           time.sleep(waitTime)
   log.logger.warning("請求消耗時間 {} 豪秒".format((time.time() - run_start_time) * 1000))
複製程式碼

資料統計

def out(length):
   log.logger.warning(f"總請求次數 {int(length)} 次")
   log.logger.warning(f"成功請求 {len(sync.success)} 次")
   log.logger.warning(f"失敗請求 {len(sync.fail)} 次")
   log.logger.warning(f"限流請求 {sync.limit} 次")
   log.logger.warning("成功率 {:.2f} %".format((len(sync.success) / int(length)) * 100))
   log.logger.warning("失敗率 {:.2f} %".format((len(sync.fail) / int(length)) * 100))
   log.logger.warning("限流百分比 {:.2f} %".format(sync.limit / int(length) * 100))
   log.logger.warning("最長請求時間 {:.2f} 毫秒".format(max(sync.response_time)))
   log.logger.warning("最短請求時間 {:.2f} 毫秒".format(min(sync.response_time)))
   log.logger.warning("平均請求時間 {:.2f} 毫秒".format(sum(sync.response_time) / len(sync.response_time)))
   # 列印成功請求的request中資訊
   for success in sync.success:
       log.logger.debug(success.content)
   # 列印失敗請求的request中資訊
   for fail in sync.fail:
       if fail is not None:
           log.logger.debug(fail.content)
複製程式碼

多執行緒請求物件

class SyncRequestTask(threading.Thread):

   def __init__(self, threadId, url, method, params, header, timeout=10):
       threading.Thread.__init__(self)
       self.setName(f"sync-{threadId}")
       self.url = url
       self.method = method
       self.params = params
       self.timeout = timeout
       self.header = header

   # 傳送請求
   def request(self):
       req = None
       try:
           if self.method == 'GET':
               req = self.doGet()
               self.add(req)
           else:
               req = self.doPost()
               self.add(req)
       except Exception as e:
           print(e)
           fail.append(req)

   def doGet(self):
       startTime = time.time()

       s = sessions.session()
       req = s.get(self.url, headers=self.header, timeout=self.timeout)
       data_build(self.getName(), time.time() - startTime)
       req.close()
       return req

   def doPost(self):
       # request_body = json.dumps(self.params)
       s = sessions.session()
       startTime = time.time()
       req = s.post(self.url, data=self.params, headers=self.header, timeout=self.timeout)
       data_build(self.getName(), time.time() - startTime)
       req.close()
       return req

   @staticmethod
   def add(request):
       global lock
       global limit
       lock.acquire()
       if request.status_code == 200:
           success.append(request)
       elif request.status_code == 429:
           limit += 1
       else:
           fail.append(request)
       lock.release()

   def run(self):
       # 開始傳送請求
       self.request()
複製程式碼

在這裡插入圖片描述在這裡插入圖片描述

相關文章