摘要
  持續性能測試能夠幫助開發團隊盡早處理難以診斷的性能及負載問題,并盡早發現重大功能缺陷。在靈活性、覆蓋度、有效性方面的優勢,使得性能測試成為持續測試的一個好選擇。
  持續集成的一個重要原則是降低改動所需耗費的時間并及早發現改動引起的問題。我們經常把這個原則稱為“快速失敗”。通過持續集成,開發團隊得以迅速查清問題根源,而不用像以前那樣等幾周甚至幾個月才開始測試。
  要實現持續集成,開發和測試團隊必須定期運行一套自動測試,并且這套自動測試的覆蓋率要足以發現重大缺陷。如果測試范圍太小,就會遺漏很多嚴重問題;如果測試時間太長,測試人員要花費很多時間才能發現缺陷。這就是為什么我們在敏捷開發中要持續推行自動化測試。
  根據我的觀察,在持續集成的環境中,滿足了三個主要因素,就能夠大幅提高測試團隊的效率:
  靈活性:測試在任何需要的時候都能運行。
  覆蓋率:在允許的時間內,盡可能提高測試的覆蓋率。
  有效性:測試要及時發現難以定位的產品缺陷。

  幾年前,當我剛開始接觸持續集成和持續測試時,相關的討論主要圍繞單元測試功能測試。開發團隊在代碼中加入單元測試,測試團隊開發出一小部分可以按需運行的功能測試自動腳本。但是性能測試大多數時候還是要等到項目快結束時才開始。大家認為,功能測試的完成,得以確保足夠的產品質量,性能測試才不會遇到功能性問題。
  通過試驗、觀察、項目進度控制上的教訓,再加上一點運氣,我們發現提早并多次進行性能測試可以顯著提高性能測試的價值。一方面得以在項目早期階段就發現棘手的問題,另一方面也增強了已經進行的功能測試的效果。
  只要看一下上面提到的三個因素,就很容易知道原因:性能測試通常都可以滿足這三個因素。因此,把性能測試納入持續測試中會是一個不錯的選擇。
  靈活性:性能測試是自動化的
  性能測試本質上來看,幾乎總是可以被自動化的,因為手動方式很難確保高負載和大容量的測試環境。和采用自動化測試相比,用鼠標連續點擊“提交”按鈕一萬次,困難得多也更難以重復。
  正因為性能測試所固有的高度自動化特性,使得它們可以在任何需要的時候被執行,不受周末及節假日影響。有了這樣的靈活性,臨下班前提交的改動也得以在晚上運行自動化測試,而不必等到測試與開發團隊第二天的上班時間。
  覆蓋率:性能測試快速覆蓋多數功能點
  性能測試通常都能在不過分深入功能點的前提下,提供足夠的主要功能覆蓋率,它能在短時間點執行到大范圍的常用功能。如果在主要功能點中存在缺陷,那它往往就會在性能測試中被捕獲。性能測試人員常會是最早發現大的功能缺陷的人。雖然這并不意味著持續性能測試可以或應該替代自動化功能測試,但是性能測試確實為功能驗證提供了有力的輔助。
  要當心不要讓性能測試實際成為功能測試,而導致團隊忘記測試的重心是在性能問題上。然而,共同進行功能測試和性能測試,確實可以有效找出產品存在的缺陷,不讓這些問題成為測試中的攔路虎。
  有效性:性能測試盡早發現難以定位的產品缺陷
  管理性能測試團隊的另一個重要經驗是:性能問題很少由專門針對性能的代碼改動引起,換句話說,性能相關的缺陷主要存在于看起來無關緊要的代碼中。往往是,改動了某段代碼,執行一次時只對性能產生非常小的影響,但是執行成千上萬次后,就會積累形成嚴重的性能問題。
  讓我們來考慮一種看似無害的情況。某行代碼的改動僅引起了每次循環10毫秒的性能延遲,假設這段代碼在單個事務中要循環10次,此時性能延遲成了100毫秒,即1/10秒。如果我們希望每秒運行上百次甚至上千次事務,這個看似非常小的性能延遲就會積累起來,嚴重降低系統每秒可以處理的事務數。
  假設開發人員在周一做了以上的代碼改動(自然,他的初衷并不是針對性能的),并從周二開始別的代碼開發工作。測試團隊在兩周后介入,發現了這個問題。此時開發人員已經進行了兩周的開發,引入問題的開發人員的工作重心已經轉移到別的四、五個模塊上。很可能當初的代碼改動太小,他甚至忘記了自己當時有做過這樣的改動。由于問題被發現時已經是在缺陷被首次引入的兩周后,開發人員和測試人員需要花費大量時間精力,很艱難地才能發現問題的根源。
  再考慮一下另一種場景:測試團隊進行了可持續的性能測試。測試人員每個晚上都進行同樣的性能測試,那么在周二早上就會發現周一晚上的測試比周末的測試結果要差。由于每天都會進行性能測試,開發人員只需要排查周一的代碼改動就能發現問題所在。
  這里的關鍵點在于,功能改動是有意為之的,它是被設計為對系統做出相應改動的;但是不利于性能提高的改動卻很少是有目的性的,更可能是其他有意為之的功能改動所造成的無心之過。
  在問題首次引入到測試發現問題之間間隔的時間越長,定位并解決這些使得系統性能下降的無心“副作用”就會變得愈發困難。如果性能測試在幾周甚至幾月內都沒有進行,對類似的性能問題進行根源分析幾乎成為不可能。盡早發現這類性能問題可以使得開發人員更好地發現根源問題并解決缺陷,從而幫助開發和測試人員在這樣大海撈針的任務上少花費時間,而是把更多的精力集中在完善發布的產品的質量上。
  擴展性能測試
  如果你還沒有做性能測試,現在就開始吧!即便是最基本的性能測試,持續運行也能帶來重大收益。從單一的事務開始,將一組測試輸入/數據作為測試的參數,并使用JMeter或Grinder之類的免費工具來擴展事務規模:每次增加一個事務,直到該樣本包括了系統中的重要事務為止?,F在的測試工具比以前的更容易使用,而且以前被認為是高級的功能在現今的多數基本工具中就有了,比如參數化、驗證系統響應、生成分布式負載、簡單報表等。
  如果你已經在做性能測試了,但只是偶爾運行或在項目收尾階段才運行,可以從已經執行的測試中選一部分來每天運行。如果受到測試環境等條件的限制,也要盡可能多地運行性能測試,哪怕每周或更久跑一次也好。關鍵在于選出可以重復運行的測試,并減少兩輪執行之間的時間,盡快地發現問題。記?。?ldquo;持續”的含義并不是“不間斷”。
  持續性能測試的結果要讓相關人員很方便查看。我建議使用儀表板(dashboard)來給出性能測試最新進展的概要報告,如果需要可以進一步查看更詳細信息。
  最重要的是,要讓測試和開發人員都參與進來,審查測試結果。就像那個森林里的樹倒下卻無人知曉的古老寓言,如果性能測試在大叫“出問題了,出問題了!”,卻沒人聽到,那么這樣的測試還有意義嗎?
  結論
  找到并修正性能問題本身就是一個非常困難的任務,更不用說要從幾周甚至幾個月的代碼改動中苦苦尋找問題根源。如果我們能縮短問題被引入和問題被發現之間的時間,那么就可以簡化排除問題的過程,避免打擊士氣,讓團隊將更多時間花在完善產品總體質量上。 因為同時具備了高靈活性、高覆蓋度和高有效性的優點,性能測試往往是持續測試的有力候選項。