1. 简介
------------
编写测试用例是一项困难且耗时的工作,但同时又是好的软件工程的重要部分。Randoop是一个随机测试的测试用例生成的工具,能够自动的为Java代码中的类生成单元测试。官网地址 https://randoop.github.io/randoop/manual/index.html ,这篇文章也是基于官网介绍Randoop的。
Writing tests is a difficult and time-consuming activity, and yet it is a crucial part of good software engineering. Randoop automatically generates unit tests for Java classes.
Randoop除了能够结合JUnit生成随机测试用例之外,还有Randoop.NET适用于微软的.NET平台,比如说C#语言等。如下例子给出了用Randoop生成的测试用例的样例(注释均是手工添加的)。
// This test shows that the JDK collection classes
// can create an object that is not equal to itself.
@Test
public static void test1() {
LinkedList list = new LinkedList();
Object o1 = new Object();
list.addFirst(o1);
// A TreeSet is an ordered collection. According to the API
// documentation, this constructor call should throw a
// ClassCastException because the list element is not Comparable. But
// the constructor silently (and problematically) accepts the list.
// 据API文档介绍,TreeSet是一个有序的集合类
// 因此在下面的t1对象声明,调用TreeSet构造方法时,由于list元素并不是可比较的
// 故此行理应抛出一个ClassCastException异常
// 但是构建方法却并没有抛出异常
TreeSet t1 = new TreeSet(list);
Set s1 = Collections.synchronizedSet(t1);
// At this point, we have successfully created a set (s1)
// that violations reflexivity of equality: it is not equal
// to itself! This assertion fails at run time on OpenJDK.
// 此时,我们已经成功创建了Set对象s1
// 但是下述的断言语句会运行失败,因为s1并不等于本身
org.junit.Assert.assertTrue(s1.equals(s1));
}
Randoop可以输出2中类型的单元测试:
- 能引发程序中的bug的揭错测试 (Error-revealing Test)
- 能用于发现未来bug的回归测试 (Regression Test)
首先,运行Randoop的揭错测试,如果发现了程序中的bug,你需要反复修改这些bug,并重新运行Randoop直到全部通过测试为止;然后,当你代码出现了版本更替后,运行Randoop的回归测试,来测试你的新版本代码。
2. 安装
------------
这里以Randdop3.1.2为例,首先在github上找到下载页 https://github.com/randoop/randoop/releases/,选择当前(2017.4)最新版本3.1.2,即randdop_3.1.2.zip。
下载之后,跟其他的JDK,Pyhon,MySql一样,需要配置环境变量,这个应该是比较轻车熟路的了,配置RANDOOP_PATH,和RANDOOP_JAR,并添加到 path 当中去。
- 设置变量RANDOOP_PATH为你的解压包路径
- 设置变量RANDOOP_JAR为你的jar文件路径
3. 运行
------------
我们通过调用Randoop的主函数(randoop.main.Main)来运行Randoop,在命令行中输入命令
java -ea randoop.main.Main [command args]
classpath路径需要包含randoop.jar的路径,以及你需要测试的Java类的路径。【注意在Windows下面冒号:要变成分号; 并且 %RANDOOP_JAR% 变成 ${RANDOOP_JAR}】
... -classpath bin:%RANDOOP_JAR% ...
产生单元测试,简单的例子,其中gentests表示生成测试的命令,参数有2个,--testclass规定了测试的类,--timelimit规定了生成的时间限制(秒)
java -ea -classpath [myclasspath];%RANDOOP_JAR% randoop.main.Main gentests
--testclass=org.yf.linear.LinkedList --timelimit=60
4. 测试生成
------------
下面以一个简单的例子来介绍Randoop如何生成单元测试的。
比如我们想要为java.util.Collection类和java.util.Arrays的单元测试。注意,Randoop只会为你指定的类来生成单元测试的。首先,创建一个myclass.txt文本文件来存放你想要测试的类,内容如下
java.util.Collections
java.util.Arrays
然后,调用Randoop如下所示,注意gentests后面可以接单个的类,即--testclass;也可以接类的文本列表,即--classlist,但注意是txt格式,且每一个类占一行。
java -ea -classpath [myclasspath];%RANDOOP_JAR% randoop.main.Main gentests
--classlist=myclass.txt --timelimit=60
在60秒之后,Randoop就会保存所产生的单元测试,最后,Randoop就会打印出JUnit文件的名字,类似如下的Java文件
由图可知,Randoop可以生成2类主要的测试集:1)ErrorTest*.RegressionTest*.java,即回归测试。所有在ErrorTest中的测试会失败,而所有在RegressionTest中的测试会通过。
5. 运行测试
在上1小节,我们讲到了如何生成ErrorTest和RegressionTest2种测试类型的单元测试,生成了各种测试文件,那么如何运行这些JUnit测试呢?我们需要调用junit.jar包和hamcrest-core.jar包,具体的执行语句如下(在我的JUnit文章中有提到过,如何借助JUnit工具执行我们的测试代码)
java -classpath .;[junit路径][hamcrest路径] org.junit.runner.JUnitCore ErrorTest
java -classpath .;[junit路径][hamcrest路径] org.junit.runner.JUnitCore RegressionTest
也可以直接把这些Java文件,复制到项目的测试包中,比如放到test包中
然后直接运行 Run As JUnit 就可以了,如下图结果
浙公网安备 33010602011771号