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分析