Eclipse(Eclipse 3.2)的新版本帶有Callisto,一套豐富的針對Eclipse 3.2的可選插件。Callisto包括一個功能強(qiáng)大的分析工具,此工具稱為Eclipse測試與性能工具平臺,簡稱TPTP。TPTP提供了一套功能全面的開源性能-測試和分析工具,包括集成的應(yīng)用程序監(jiān)控、測試、跟蹤和分析功能,以及靜態(tài)代碼分析工具。對于在各類Java應(yīng)用程序中找出和識別性能問題,分析工具的價值是不可估計的。在本文中,我們將探討如何使用TPTP來保證獲得高質(zhì)量和高性能的代碼(甚至是在單元和集成測試中)。
安裝TPTP
安裝TPTP容易的方式是使用Remote Update站點(diǎn)(參見圖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.從遠(yuǎn)程站點(diǎn)安裝TPTP
分析Java應(yīng)用程序
測試與性能工具平臺基本上是一套分析工具。分析應(yīng)用程序通常涉及到觀察應(yīng)用程序在壓力之下的處理方式。這樣做的一種常見方式是對已部署的應(yīng)用程序運(yùn)行一組負(fù)載測試,然后使用分析工具來記錄應(yīng)用程序的行為。接著,可以對結(jié)果進(jìn)行研究來調(diào)查任何性能問題。這些事情通常是在項(xiàng)目結(jié)束時進(jìn)行的,因?yàn)榇藭r應(yīng)用程序幾乎已經(jīng)準(zhǔn)備好進(jìn)入生產(chǎn)階段了。
TPTP非常適合這類任務(wù)。一個典型的用例是使用像JMeter這樣的工具來運(yùn)行負(fù)載測試,然后使用TPTP歸納工具記錄和分析性能統(tǒng)計數(shù)據(jù)。
然而,這并非使用TPTP分析應(yīng)用程序的方式。通常,越早進(jìn)行測試,后面遇到的問題越少。借助TPTP,您可以在很多上下文中分析代碼,包括JUnit測試用例、Java 應(yīng)用程序和web應(yīng)用程序。而且它很好地集成到了Eclipse IDE中。所以,沒有理由不在早期開始初步性能測試和分析工作。
TPTP讓您可以測試應(yīng)用程序行為的幾個方面,包括內(nèi)存使用(創(chuàng)建了多少對象,這些對象的大小如何)、執(zhí)行統(tǒng)計數(shù)據(jù)(應(yīng)用程序在哪些地方所花的時間較多)和測試覆蓋(測試期間執(zhí)行代碼的確切數(shù)量)。每個方面均可提供有關(guān)應(yīng)用程序性能的獨(dú)立信息。
不管怎么說,內(nèi)存泄漏可能而且的確存在于Java中。創(chuàng)建(并保存)不必要的對象會增加對內(nèi)存的需求,并加重垃圾收集器的工作負(fù)擔(dān),這都會損害應(yīng)用程序的性能。而且,如果運(yùn)行應(yīng)用程序的服務(wù)器的持續(xù)正常運(yùn)行時間很長,累積下來的內(nèi)存泄漏可能終導(dǎo)致應(yīng)用程序崩潰或服務(wù)器停止運(yùn)行。這些都是留心應(yīng)用程序內(nèi)存泄漏情況的充分理由。
根據(jù)80-20經(jīng)驗(yàn)法則,80%的性能問題出現(xiàn)在20%的代碼中;蛘,換句話說,只要把精力集中在應(yīng)用程序中執(zhí)行經(jīng)常的部分上,可以花費(fèi)相對較少的氣力使性能有實(shí)質(zhì)性的提高。在這種情況下,執(zhí)行統(tǒng)計數(shù)據(jù)可以派上用場了。
除此以外,TPTP還提供一些基本的測試覆蓋數(shù)據(jù)。盡管這些統(tǒng)計數(shù)據(jù)不如Cobertura或Clover這樣的專用工具提供的完整,您仍然可以通過它們快速了解性能測試正在有效地測試哪些方法。
在本文中,我討論的測試種類同樣是沒有經(jīng)過優(yōu)化的。優(yōu)化涉及到使用像緩沖這樣的技術(shù)對應(yīng)用程序性能進(jìn)行微調(diào)。這是一項(xiàng)對技術(shù)要求很高的操作,好留到項(xiàng)目的后完成。
這里所討論的這種初步性能測試和分析僅僅包括,確保應(yīng)用程序從一開始正確執(zhí)行,以及沒有編碼錯誤或糟糕的編碼實(shí)踐會在后面的階段中對性能產(chǎn)生不利的影響。事實(shí)上,修復(fù)內(nèi)存泄漏和避免不必要的對象創(chuàng)建并不是優(yōu)化——這只不過是調(diào)試,而且同樣應(yīng)該盡可能早地完成。
讓我們通過使用一些單元測試來分析一個類的方式開始?梢苑治龀R(guī)的單元或集成測試,或者編寫針對性更強(qiáng)的面向性能的測試。通常,您應(yīng)該嘗試分析與生產(chǎn)代碼接近的代碼。許多人使用模擬對象來代替DAO對象進(jìn)行單元測試,使用這項(xiàng)功能強(qiáng)大的技術(shù)可以加速開發(fā)生命周期。如果使用這類方法,一定要使用這些測試來運(yùn)行分析工具,它可以揭示有關(guān)內(nèi)存使用和測試覆蓋的有用信息。然而,性能測試的價值是有限的,因?yàn)閷τ谂c數(shù)據(jù)庫相關(guān)的應(yīng)用程序來說,其性能往往是由數(shù)據(jù)庫的性能所決定的,所以在這個上下文中,應(yīng)該進(jìn)行所有重要的性能測試。簡而言之,不要忘了分析基于實(shí)際數(shù)據(jù)庫而運(yùn)行的集成測試。
出于本文的需要,我們將對以下類進(jìn)行測試,這個類代表了一個到庫目錄的簡單接口。
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",這將打開一個向?qū)В梢栽谄渲信渲貌煌N類的測試分析,如圖2所示。
圖 2. 創(chuàng)建一個TPTP分析