標籤:repo plot origin func ima scripts adr tip 完成
http://www.aikaiyuan.com/5318.html
對Web服務做Performance & Load測試,最常見的工具有Apache Benchmark俗稱ab和商用工具LoadRunner。ab簡單直接,功能也相對較弱,但我們經常看到的對一些Web server或者Framework的效能測試用的ab做的,而LoadRunner功能也確實很強大,各種大型軟體公司、軟體外包企業幾乎是必備了,用起來很High,當然其價格也確實很High
這裡要介紹的multi-mechanize(這名忒難記)是一款用Python開發的Performance & Load測試載入器,是由Pylot的作者新近開發的,算是升級換代的產品。用multi-mechanize可以通過編寫Python指令碼來實現較複雜的測試邏輯,其並發測試是通過multiprocessing(多進程)和多線程機制來實現的。
1. 安裝萬能的pip&easy_installpip install multi-mechanize mechanize numpy matplotlib
- mechanize是一個類比browser行為的一個庫,當然你也可以用其它的如urllib2、request、tornado.httpclient等等庫,不是必須。
- 後面兩個numpy和matplotlib也是可選的,當你需要它自動產生圖形化報表時才會用到,安裝matplotlib你的系統有可能需要安裝libpng和freetype庫。
2. 使用方法
multimech-newproject my_project
自動建立一個my_project目錄,子目錄test_scripts用來放測試指令碼,config.cfg是測試組態,主要要配的是測試時間、測試指令碼和並發threads量。
## Copyright (c) 2010 Corey Goldberg ([email protected])# License: GNU LGPLv3## This file is part of Multi-Mechanize#import mechanizeimport timeclass 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來是不是覺得非常不方便?不用急,針對這點,後面的小技巧部分會另闢蹊徑給你指條明路。
multimech-run my_project
測試結果報表和未經處理資料將放到results目錄下按測試時間產生的子目錄中,生產的html版本的結果統計如所示:
3. 使用小技巧
如果使用的是mechanize,可以通過下面的方式,從上面的browser對象br裡擷取到cookie資訊。
br._ua_handlers[“_cookies”].cookieja
- 單個指令碼多個測試案例的支援:這個思路來源於testsuite的概念,同一個testsuite裡的case作為一組相關的case可以共用一些代碼邏輯和資源(如browser對象),而multi-mechanize預設的方式是不支援的,要實現這一點,只需要一點小小的技巧即可,上代碼:
base.py,Transaction基類:
# -*- coding: utf-8 -*-import mechanizeimport timeimport tracebackimport loggingclass 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網站:
# -*- coding: utf-8 -*-from base import BaseTransactionclass Transaction(BaseTransaction): def test_google_com_hk(self): # 測試邏輯代碼,如類似於上面的測試example.com pass def test_google_com_sg(self): pass def test_google_com(self): pass
- 真實的並發量計算:multi-mechanize使用了multiprocessing庫,會同時起多個進程,且每個進程按config裡的配置起多個線程來實現並發測試,但真正的單位時間內的並發量並不是config裡設定threads=10這樣的表示每秒10個並發,真實的並發量需要根據最終完成的transaction數和這些transaction裡麵包含多少次http請求和總的完成時間來計算得知,這點不是很直觀。
- 自訂統計資料:你可以往self.custom_timers這個內建的字典裡塞任意的自訂統計資料,他們在報表中都能夠得到體現。
更多的文檔和一手資料請參考文檔http://testutils.org/multi-mechanize/和git程式碼程式庫https://github.com/cgoldberg/multi-mechanize 。最後multi-mechanize還不是很好用,一是使用過程中發現有一些情況會拋異常,導致不能正確產生報表,另一個彆扭的是case的編寫不是unittest那一套,是作者自創Transaction流:)
Python Web 效能和壓力測試 multi-mechanize