http://www.aikaiyuan.com/5318.htmlhtml
對Web服務作Performance & Load測試,最多見的工具備Apache Benchmark俗稱ab和商用工具LoadRunner。ab簡單直接,功能也相對較弱,但咱們常常看到的對一些Web server或者Framework的性能測試用的ab作的,而LoadRunner功能也確實很強大,各類大型軟件公司、軟件外包企業幾乎是必備了,用起來很High,固然其價格也確實很Highgit
這裏要介紹的multi-mechanize(這名忒難記)是一款用Python開發的Performance & Load測試工具,是由Pylot的做者新近開發的,算是升級換代的產品。用multi-mechanize能夠經過編寫Python腳原本實現較複雜的測試邏輯,其併發測試是經過multiprocessing(多進程)和多線程機制來實現的。github
multimech-newproject my_project
自動建立一個my_project目錄,子目錄test_scripts用來放測試腳本,config.cfg是測試配置,主要要配的是測試時間、測試腳本和併發threads量。apache
# # Copyright (c) 2010 Corey Goldberg (corey@goldb.org) # License: GNU LGPLv3 # # This file is part of Multi-Mechanize # import mechanize import time class Transaction(object): def __init__(self): self.custom_timers = {} def run(self): br = mechanize.Browser() br.set_handle_robots(False) start_timer = time.time() resp = br.open('http://www.example.com/') resp.read() latency = time.time() - start_timer self.custom_timers['Example_Homepage'] = latency assert (resp.code == 200), 'Bad HTTP Response' assert ('Example Web Page' in resp.get_data()), 'Failed Content Verification' if __name__ == '__main__': trans = Transaction() trans.run() print trans.custom_timers
注意:按multi-mechanize的默認規則,每一個腳本必須有一個Transaction的類,類要有一個run方法,在run裏面寫測試業務邏輯。這個例子是打開http://www.example.com,記錄訪問所耗時長,很是簡單明瞭,而實際的場景你可能須要有用戶登陸、而後測試某個或多個頁面(API),只是測試業務複雜一些,寫法是相似的。一個腳本文件只能有一個Transaction的類、類也只能有一個run方法,寫起case來是否是以爲很是不方便?不用急,針對這點,後面的小技巧部分會另闢蹊徑給你指條明路。cookie
multimech-run my_project
測試結果報表和原始數據將放到results目錄下按測試時間生成的子目錄中,生產的html版本的結果統計以下圖所示:多線程
若是使用的是mechanize,能夠經過下面的方式,從上面的browser對象br裏獲取到cookie信息。併發
br._ua_handlers[「_cookies」].cookiejaapp
base.py,Transaction基類:ide
# -*- coding: utf-8 -*- import mechanize import time import traceback import logging class BaseTransaction(object): _TEST_CASE_PREFIX = "test_" def __init__(self): self._init() self.custom_timers = {} self.browser = mechanize.Browser() self.browser.set_handle_robots(False) self.browser.set_handle_redirect(True) self.browser.set_handle_referer(True) def _init(self): self.funcs = [] funcs_ = dir(self) for func_ in funcs_: if func_.startswith(self._TEST_CASE_PREFIX): self.funcs.append(func_) def run(self): """"全部繼承BaseTransaction的類,只須要在以test_開頭的方法裏實現測試case便可,運行時多個case均可以獲得測試""" try: for func in self.funcs: start_timer = time.time() getattr(self, func)() # run test latency = time.time() - start_timer self.custom_timers['%s' % func[len(self._TEST_CASE_PREFIX):]] = latency except Exception, e: logging.error(traceback.format_exc()) raise e
test_case_google.py裏是真正的測試case,這裏是同時測試多個google站點:tornado
# -*- coding: utf-8 -*- from base import BaseTransaction class Transaction(BaseTransaction): def test_google_com_hk(self): # 測試邏輯代碼,如相似於上面的測試example.com pass def test_google_com_sg(self): pass def test_google_com(self): pass
更多的文檔和一手資料請參考文檔http://testutils.org/multi-mechanize/和git代碼庫https://github.com/cgoldberg/multi-mechanize 。最後multi-mechanize還不是很好用,一是使用過程當中發現有一些狀況會拋異常,致使不能正確生成報表,另外一個別扭的是case的編寫不是unittest那一套,是做者自創Transaction流:)