在面試測試人員的時候,這是一個很好的問題:你如何定義效能/負載/壓力測試?在很多時候,人們都是將它們作為可互相替換的相同術語來使用,然而實際上他們之間的差異是比較大的。這個貼子是根據我自己的一些經驗,針對這三個概念寫的一個比較簡單的評論,當然也同時參考了一些測試文獻資料裡的定義,比如說:
"Testing computer software" by Kaner et al
"Software testing techniques" by Loveland et al
"Testing applications on the Web" by Nguyen et al
效能測試
效能測試的目的不是去找bugs,而是排除系統的瓶頸,以及為以後的迴歸測試建立一個基準。而效能測試的操作,實際上就是一個非常小心受控的測量分析過程。在理想的情況下,被測軟體在這個時候已經是足夠穩定了,所以這個過程得以順利的進行。
一組清晰已定義好的預期值是讓一次有意義的效能測試的基本要素。如果連你自己都不知道系統效能有些什麼是要測的,那麼它對於你要測試的方法手段是沒有指導意義的*。例如,給一個web應用做效能測試,你要知道至少兩樣東西:
在不同並發使用者數或者HTTP串連數情況下的負載預期值*
可接受的回應時間
當你知道你的目標後,你就可以開始使用對系統持續增加負載的方法來觀察系統的瓶頸所在。重新拿web應用系統來做例子,這些瓶頸可存在於多個層次,你可以使用多種工具來查明它們的所在:
在應用程式層,開發人員可以通過profilers來發現低效率的代碼,比如說較差的尋找演算法
在資料庫層,開發人員和資料庫管理員(DBA)可以通過特定的資料庫profilers及事件探查器*(query optimizers)
在作業系統層,系統工程師可以使用一些工具如在Unix類的作業系統中的top,vmstat,iostat,在Windows系統中的PerfMon來監控CPU,內在,swap,磁碟I/O等硬體資源;專門的核心監視軟體也可以在這一層面上被使用。
在網路層上,網路工程師可以使用報文探測器(如tcpdump),網路通訊協定分析器(如ethereal),還有其它的工具(如netstat,MRTG,ntop,mii-tool)
從測試的觀點來看,上面所有描述的活動都是一種白盒的方法,它對系統從內到外及多角度進行審查及監控。測度資料*被取得及分析後,對系統的調整則成為理所當然的下一個步驟。
然而,(除了上面的方法外)測試人員在給被測系統運行負載實驗*(這裡為了不與我們所理解的負載測試-load testing的概念搞混,特譯做負載實驗)的時候,也採取了黑盒的方法。像對於WEB應用來講,測試人員可以使用工具來類比並發使用者或者HTTP串連及測量回應時間。在我以前使用過的輕量級的負載測試開源工具有ab,siege,httperf。一個更重量級的工具是OpenSTA,但我沒用過。我也還沒有用過The Grinder這個工具,但它在我將要做的事情中排名靠前。
當負載實驗*的結果顯示出系統的效能來沒有達到它的預期目標時,這就是要對應用和資料庫的調整的時候了。同時你要確保讓你的代碼運行得儘可能高效,以及資料庫在給定的作業系統和硬體設定的情況下最佳化。測試驅動開發(TDD)的實踐者會發現這種上下文結構架構是非常有用的*,如可以通過負載實驗*及時間實驗的函數性*來增強現存單元測試代碼的Mike Clark的jUnitPerf*。當一個特定的函數或者方法被剖析過*和調試過後,開發人員就可以在jUnitPerf中,放入它的單元實驗*來確保它可以達到負載及時間上的效能需求。Mike Clark稱這為“持久性能測試”。我順便也提一下我已經做了一個基於Python的jUnitPerf的初步研究,我稱之為pyUnitPerf.
假若在調試過應用程式及資料庫後,系統還是沒有達到效能的預期目標,在這種情況下,還是有一些其它的調試的流程*可以針對前面講過的那幾個層次來使用的。下面就是一些在應用程式代碼*之外仍可以提高WEB應用系統效能的例子:
使用WEB緩衝裝制,如Squid提供的裝置
將高訪問量的網頁靜態化,以避免這些高訪問量對資料庫進行大量的調用
通過Server Load Balancer的方法來水平縮放WEB伺服器的結構*
在水平縮放資料庫群及將它們分為讀寫伺服器和唯讀伺服器後,還要對唯讀伺服器群Server Load Balancer。*
通過增加更多的硬體資源(CPU,記憶體,磁碟等)縱向的縮放WEB及資料庫伺服器群
增加網路的頻寬
由於現在的WEB應用系統都是十分複雜的系統,效能調試有時要具有一些藝術性才行。在每次修改一個變數及重新測度的時候一定要非常小心,否則的話,在變化中將會有很多難於確定和重複的不確定因素*。
在一個規範的測試環境比如說一個測試實驗試,它是不會常常的重現實際應用時的伺服器配置環境。在這樣的情況下,分段測試環境,也就是生產實際環境的一個子集就可以派上用場了。但同時系統的期望效能也需要相應的調低一點。
“運行負載實驗*->測度效能->調試系統”這個迴圈一直要被重複執行到被測試系統達到了期望的效能標準了才可以停。在這個時候,測試人員就可以明了在正常條件下的系統運轉怎麼樣,同時這些就可以做為以後在迴歸測試中,評價新版本的軟體效能的一個標準了。
效能測試還有另一個目標就是建立一組被測系統的基準資料。在很多行業中都會有這種行業標準的基準資料,比如說TPC公布的。還有很多軟硬體廠家都為了在TCP排名中靠前而對他們的機器進行精心調試。所以說你應當非常謹慎的說明在你進行測試的時候,並沒有在種類繁多的軟硬體產品中進行全部測試*。
負載測試
我們都已經在效能測試調試的過程中,見識過負載測試了。在那種環境中,它意味著通過自動化工具來持續對系統增加負載。但對於WEB應用來講,負載則是並發使用者或者HTTP串連的數量。
術語“負載測試”在測試文獻資料中通常都被定義為給被測系統加上它所能操作的最大任務數的過程。負載測試有時也會被稱為“容量測試”,或者“耐久性測試/持久性測試”*
容量測試的例子:
通過編輯一個巨大的檔案來測試文文書處理軟體
通過發送一個巨大的作業來測試印表機
通過成千上萬的使用者郵箱來測試郵件伺服器
有一種比較特別的容量測試是叫作“零容量測試”,它是給系統加上空任務來測試的。
耐久性測試/持久性測試的的例子:
在一個迴圈中不停的運行用戶端超過一個擴充時間段*。
負載測試的目的:
找到一些在測試流程中前面的階段所進行的粗略測試中沒有被找出的bugs,例如,記憶體管理bugs,記憶體泄露,緩衝器溢出等等。
保證應用程式達到效能測試中確定的效能基準。這個可以在運行迴歸實驗時,通過載入特定的最大限度的負載來實現。
儘管效能測試和負載測試似乎很像,但他們的目的還是有差異的。一方面,效能測試使用負載測試的技術,工具,以及用不同的負載程度來測度和基準化系統。在另一方面來講,負載測試是在一些已經定義好的負載程度上進行測試的,通常對系統加上最大負載之後,系統應該仍然可以提供全部功能。這裡需要明確一點,負載測試並不是要對系統載入上過度的負載而使系統不能工作,而是要使系統像一個上滿了油的機器嗡嗡叫*。
在負載測試的相關內容中,我想應該非常重要的是要有十分充足的資料來進行測試。從我的經驗中得知,假若不用非常大的資料*去測的話,有很多嚴重的bug是不會的到的。比如說,LDAP/NIS/Active Directory資料庫中成千上萬的使用者,郵件伺服器中成千上萬的郵箱,資料庫中成G成G的表,檔案系統中很深的檔案或者目錄的層次,等等。顯然,測試人員就需要使用自動化工具來產生這些龐大的資料集,比較幸運的是任何優秀的指令碼語言都可以勝任這些工作。
壓力測試
壓力測試是指通過對系統載入過度的資源或者例系統沒有應該具有的令系統可以正常運作的資源,來使系統崩潰(在某些情況的時候,它又可以叫做負面測試)。進行這個瘋狂行為的主要目的是為了保證系統出故障及可以適當的恢複,而這個恢複得怎麼樣的特性則是叫做可恢複性。
當效能測試需要的是一個可控制的環境和不斷的測度的時候,壓力測試則是令為歡喜的引起混亂及不可預測性(譯者按:從這一點可以看出作者是一個很優秀的測試人員)。還是舉WEB應用系統為例,下面是一些對系統可行的壓力測試方法:
兩倍的已經基準的並發使用者數或者HTTP串連數
隨機的關閉及重開串連到伺服器上的網路上集線器/路由器的連接埠(例如,可以通過SNMP命令來實現)
把資料庫斷線然後再重啟
當系統還在啟動並執行時候,重建一個RAID陣列
在WEB和資料庫伺服器上運行消耗資源(如CPU,記憶體,磁碟,網路)的進程
我可以肯定一些經常使用非常規方法來破壞系統的測試人員可以進一步充實這個列表的。只是壓力測試並不是簡單的為了一種破壞的快感而去破壞系統,實際上它是可以讓測試工程師觀察系統對出現故障時系統的反應。系統是不是儲存了它出故障時的狀態?是不是它就突然間崩潰掉了?它是否只是掛在那兒啥也不做了?它失效的時候是不是有一些反應*?在重啟之後,它是否有能力可以恢複到前一個正常啟動並執行狀態?它是否會給使用者顯示出一些有用的錯誤資訊,還是只是顯示一些很難理解的十六進位代碼?系統的安全性是否為因為一些不可預料的故障而會有所降低?這些問題可以一直問下去的。
結論
我明白我只是提到一些在效能/負載/壓力測試中應該值得注意的一些比較基礎的問題,工具及方法。我個人覺得效能測試及調試是一個很有趣的話題,我將會在以後貼更多的相關內容上來的。