Eclipse(Eclipse 3.2)的新版本帶有Callisto,一套豐富的針對Eclipse 3.2的可選插件。Callisto包括一個功能強大的分析工具,此工具稱為Eclipse測試與性能工具平臺,簡稱TPTP。TPTP提供了一套功能全面的開源性能-測試和分析工具,包括集成的應用程序監控、測試、跟蹤和分析功能,以及靜態代碼分析工具。對于在各類Java應用程序中找出和識別性能問題,分析工具的價值是不可估計的。在本文中,我們將探討如何使用TPTP來保證獲得高質量和高性能的代碼(甚至是在單元和集成測試中)。
安裝TPTP
安裝TPTP容易的方式是使用Remote Update站點(參見圖1)。打開Remote Update窗口(Help -> Software Updates -> Find and Install),然后選擇Callisto Discovery Site。Eclipse將建議安裝Callisto插件集。TPTP工具列在“Testing and Performance”下面。容易也是耗時的選擇,是安裝所有建議的插件。即使不安裝整個Callisto工具集,您仍然需要安裝一些其他TPTP需要的組件,例如"Charting and Reporting"、"Enabling Features"和"DataTool Performance"。
圖 1.從遠程站點安裝TPTP
分析Java應用程序
測試與性能工具平臺基本上是一套分析工具。分析應用程序通常涉及到觀察應用程序在壓力之下的處理方式。這樣做的一種常見方式是對已部署的應用程序運行一組負載測試,然后使用分析工具來記錄應用程序的行為。接著,可以對結果進行研究來調查任何性能問題。這些事情通常是在項目結束時進行的,因為此時應用程序幾乎已經準備好進入生產階段了。
TPTP非常適合這類任務。一個典型的用例是使用像JMeter這樣的工具來運行負載測試,然后使用TPTP歸納工具記錄和分析性能統計數據。
然而,這并非使用TPTP分析應用程序的方式。通常,越早進行測試,后面遇到的問題越少。借助TPTP,您可以在很多上下文中分析代碼,包括JUnit測試用例、Java 應用程序和web應用程序。而且它很好地集成到了Eclipse IDE中。所以,沒有理由不在早期開始初步性能測試和分析工作。
TPTP讓您可以測試應用程序行為的幾個方面,包括內存使用(創建了多少對象,這些對象的大小如何)、執行統計數據(應用程序在哪些地方所花的時間較多)和測試覆蓋(測試期間執行代碼的確切數量)。每個方面均可提供有關應用程序性能的獨立信息。
不管怎么說,內存泄漏可能而且的確存在于Java中。創建(并保存)不必要的對象會增加對內存的需求,并加重垃圾收集器的工作負擔,這都會損害應用程序的性能。而且,如果運行應用程序的服務器的持續正常運行時間很長,累積下來的內存泄漏可能終導致應用程序崩潰或服務器停止運行。這些都是留心應用程序內存泄漏情況的充分理由。
根據80-20經驗法則,80%的性能問題出現在20%的代碼中。或者,換句話說,只要把精力集中在應用程序中執行經常的部分上,可以花費相對較少的氣力使性能有實質性的提高。在這種情況下,執行統計數據可以派上用場了。
除此以外,TPTP還提供一些基本的測試覆蓋數據。盡管這些統計數據不如Cobertura或Clover這樣的專用工具提供的完整,您仍然可以通過它們快速了解性能測試正在有效地測試哪些方法。
在本文中,我討論的測試種類同樣是沒有經過優化的。優化涉及到使用像緩沖這樣的技術對應用程序性能進行微調。這是一項對技術要求很高的操作,好留到項目的后完成。
這里所討論的這種初步性能測試和分析僅僅包括,確保應用程序從一開始正確執行,以及沒有編碼錯誤或糟糕的編碼實踐會在后面的階段中對性能產生不利的影響。事實上,修復內存泄漏和避免不必要的對象創建并不是優化——這只不過是調試,而且同樣應該盡可能早地完成。
讓我們通過使用一些單元測試來分析一個類的方式開始。可以分析常規的單元或集成測試,或者編寫針對性更強的面向性能的測試。通常,您應該嘗試分析與生產代碼接近的代碼。許多人使用模擬對象來代替DAO對象進行單元測試,使用這項功能強大的技術可以加速開發生命周期。如果使用這類方法,一定要使用這些測試來運行分析工具,它可以揭示有關內存使用和測試覆蓋的有用信息。然而,性能測試的價值是有限的,因為對于與數據庫相關的應用程序來說,其性能往往是由數據庫的性能所決定的,所以在這個上下文中,應該進行所有重要的性能測試。簡而言之,不要忘了分析基于實際數據庫而運行的集成測試。
出于本文的需要,我們將對以下類進行測試,這個類代表了一個到庫目錄的簡單接口。
interface Catalog { List<Book> findBooksByAuthor(String name); List<Book> findAllBooks();}
基本的單元測試如下:
public class CatalogTest extends TestCase { ... public Catalog getCatalog() { ... } public void testFindBooksByAuthor() { List<Book> books = getCatalog().findBooksByAuthor("Lewis"); } public void testLoadFindBooksByAuthor() { for(int i = 0; i < 10; i++) { List<Book> books = getCatalog().findBooksByAuthor("Lewis"); } } public void testFindAll() { List<Book> books = getCatalog().findAllBooks(); }}
您需要做的第一件事情是建立一個分析。在Eclipse主菜單中選擇"Run -> Profile",這將打開一個向導,您可以在其中配置不同種類的測試分析,如圖2所示。
圖 2. 創建一個TPTP分析