上述代码的执行结果为:
清单 8. p-unit 参数化测试案例输出
[solo] Started running samples.ParamTestClass
samples.ParamTestClass
testA(10) - [57936.0bytes,447.0ms]
testA(20) - [33128.0bytes,61.0ms]
testB(10) - [24832.0bytes,137.0ms]
testB(20) - [0.0bytes,63.0ms]
testC(10) - [83560.0bytes,468.0ms]
testC(20) - [16528.0bytes,47.0ms]
total: 6, failures:0 (GREEN) 1450.0ms
从上述结果看出,每个方法被执行了 2 次,每次传入不同的参数。多线程运行参数化测试程序?相信读者已经明白怎么去实现了,只需将 PUnitSoloRunner 替换成 PUnitConcurrentRunner。
运行环境测试案例
随着 Java 开源,出现了更多的 Java 运行环境,除了 SUN 的参考实现外,BEA、IBM 均有自己的 Java 运行环境,更有如 Apache Harmony 的开源运行环境(尽管现在 Apache Harmony 尚不能称为 Java 运行环境)。运行环境测试案例,为运行环境开发者以及选择运行环境,都能提供一定的帮助。比如说下面的例子是测试 java.util.ArrayList 和 java.util.Vector 在两个不同运行环境的表现。测试案例写法和普通的测试案例完全一样,我们只需告诉 p-unit 不同的运行环境的 Java 路径以及正确的 classpath,然后调用 runVMs 函数即可:
清单 9. p-unit 运行环境测试案例
public static void main(String[] args) {
PUnitSoloRunner runner = new PUnitSoloRunner();
runner.addPUnitEventListener(new OverviewReporter(new ImageRender()));
runner.runVMs(ListTestClass.class, new VM[] { VMConfig.HARMONY, VMConfig.SUN });
}
public class VMConfig {
private static String CLASSPATH = " -cp correct_classpath_including_all_jars_and_path";
private static String HARMONY_PATH = "harmony_path\bin\java" + CLASSPATH;
private static String SUN_PATH = "sun_path\bin\java" + CLASSPATH;
public static VM HARMONY = new VM(HARMONY_PATH, "HARMONY");
public static VM SUN = new VM(SUN_PATH, "SUN");
}
public class ListTestClass {
private static final int LIST_COUNT = 100000;
private static Object element = new Object();
private Random indexGenerator = new Random();;
public void testInsertArrayList() {
ArrayList arrayList = new ArrayList(LIST_COUNT);
insertSequence(arrayList);
insertRandom(arrayList);
}
public void testInsertVector() {
Vector vector = new Vector(LIST_COUNT);
insertSequence(vector);
insertRandom(vector);
}
public void insertSequence(List list) {
for (int i = 0; i < LIST_COUNT; ++i) {
list.add(element);
}
}
public void insertRandom(List list) {
for (int i = 0; i < LIST_COUNT; ++i) {
list.add(indexGenerator .nextInt(LIST_COUNT),element);
}
}
}
上述代码的运行结果如下:
图 1. 运行环境测试案例结果
从上图中可以很直观的看出,笔者使用的 HARMONY 版本在该测试案例中速度更快(左图),但内存消耗更多(右图)。下一节将讲述如何输出报表,但或许你已经注意到了,代码非常简单。
从上面的实例中我们已经看到 p-unit 的输出结果的两种形式,控制台和报表图片。默认情况下,p-unit 将输出到控制台。p-unit 采用事件机制,在运行器的每个节点都会提供通知事件。所有的输出都是通过注册事件响应器来实现的。这也表明了结果输出和运行器完全隔离,用户也可以定制自己的报表。p-unit 有 4 种内建输出,分别为控制台、文件、图片报表以及 PDF 报表。上一节的例子中我们已经看到图片报表,其代码为:
清单 10. 添加 p-unit 总体图片报表
runner.addPUnitEventListener(new OverviewReporter(new ImageRender()));
p-unit 内建的报表有分三种不同的粒度:总体级别(OverviewReporter),TestSutie 级别(TestSuiteReporter),以及测试案例类级别(TestClassReporter)。这三种级别都可以输出图片格式或是 PDF 格式,因此,总共有六种类型的输出。上述的代码是输出总体级别的图片。由于事件监听器是互相独立的,因此你可以既选择输出图片又选择输出 PDF 文件,只需再添加事件监听器即可:
清单 11. 添加多个 p-unit 事件监听器
runner.addPUnitEventListener(new OverviewReporter(new ImageRender()));
runner.addPUnitEventListener(new OverviewReporter(new PDFRender()));
总结
至此,你是否基本理解了 p-unit 的概念呢?简单,易用,关注多线程,关注性能,这是 p-unit。此外 p-unit 还有很多很好的小特性,如 Alphabetical 接口来保证执行测试函数的先后顺序等。使用 p-unit,让你的代码更健壮!