【IT168 技术文章】
引言
一个例子
我们先看一个例子,以了解对”规则”做单元测试的特点。我们有一个性能调优工具 WPA, 它能够将与性能相关的参数的值进行评估并推荐最优值。它的评估和推荐最优值算法都是基于”规则”的。
Java 虚拟机的初始堆大小(JVM initial heap size)是一个影响 JVM 的性能的关键参数。性能调优工具 WPA 有一套规则对“ JVM initial heap size ”的值进行评估(参见清单 1)。评估的结果有 5 个级别。级别“ 1 ”表示设置良好,可提高性能;级别“ 5 ”表示设置很差,会降低性能。
清单 1. JVM initial heap size rating algorithm 在这一套规则中,包含很多不同的条件(见“ IF-ELSE ”语句)。在测试时(单元测试和功能测试),我们需要至少 24 组测试数据以覆盖所有的阀值(threshold value)和等价类(equivalent class)。参见表 1。
2 Rating3LowerBounds = 48
3 Rating5UpperBounds = 1536
4 Rating5LowerBounds = 32
5 Rating3Multiplier = 4
6 Rating5Multiplier = 3
7
8 absoluteMaximumValue= Math.min(currentMemoryPoolSize, overallMemoryOnPartition)
9 / Rating3Multiplier
10 if (initialHeapSize > absoluteMaximumValue) {
11 return 4;
12 }
13 if ((initialHeapSize < Rating5LowerBounds) ||
14 (initialHeapSize > Rating5UpperBounds)) {
15 rating = severe problem (5)
16 }
17 else if ((initialHeapSize < Rating3LowerBounds) ||
18 (initialHeapSize > Rating3UpperBounds)) {
19 rating = probable problem (3)
20 }
21 ……
22 }
23 if (initialHeapSize * Rating5Multiplier > currentMemoryPoolSize)
24 {
25 return severe problem (5)
26 }
27 else if(initialHeapSize*Rating3Multiplier > currentMemoryPoolSize)
28 {
29 return max(rating, 3)
30 }
31 else if(initialHeapSize*Rating2Multiplier > currentMemoryPoolSize)
32 else {
33 return max(rating, 1)
34 }
对”规则”做单元测试
从“JVM initial heap size rating algorithm”以及 WPA 中其他基于“规则”的性能调优算法,我们总结出对“规则”做单元测试的特点有:
一、为了覆盖所有的阀值 (threshold value )和等价类 (equivalent class ),我们需要大量测试数据。单元测试的通常做法是,把所有的测试数据写入测试代码中。对比以格式化的形式(XML,Excel 等)来保存测试数据,这样做使得这些数据不容易维护和复用。
二、由于对”规则”的测试涉及到变量,这些变量来自运行时的输入,我们在单元测试之前就需要构建运行时环境,这种工作可能非常复杂。如果一套”规则”中包含更多的条件和输入参数,以上两个问题会更加严重
三、在一个基于”规则”的系统里,”规则”之间有很多共性,我们没有必要对每一个”规则”都写一个测试类。
本文将给出解决以上问题的一种做法。本文的组织结构如下:
编写 Mock 类:利用 Mock 对象来代替实时运行环境;
将测试数据保存到配置文件中:利用格式化文档实现测试数据的复用性和可维护性;
编写 SettersMap 类:这个类保存了配置文件中的数据并提供了获取这些数据的接口;
编写可复用的 TestCase 类:创建 JUnit 的扩展类以适应对“规则”做单元测试的需求;
用 TestSuite 组织测试用例:用 TestSuite 把测试用例组织起来;
在以下内容中,我们将拿“ JVM initial heap size rating algorithm ”做例子。