最近在看《重构-改善既有代码结构》一书,里面提到,要有一个好的测试环境。作者采用的是Junit来进行单元测试,正好我也是这么做的。关于Junit,还是有很同学不清楚他的用途,或者说具体怎么用,所以决定有空的时候就简单讲讲关于他使用。
首先讲讲Junit目前主流的两个版本:3.x和4.0,两者在使用上有很大差别的,Junit4的发布,可以说是该类库历史上的一次具有里程碑意义的更新。它的新特性主要是通过采用 Java 5 中的标记(annotation)而不是利用子类、反射或命名机制来识别测试,从而简化测试。老版本的Junit类,一般位于:Junit包下,而4。0版本的则位于org.junit包下,这个是需要注意的。
其实在写本文的时候,我在想,要不要给讲老版本的使用?既然新版本更优秀,何不直接讲新版的使用,但是新版优秀在那里列?估计很多人答不出一二三,所以还是决定多花一点时间,将老版本与新版本都出来,让大家有一个更全面的了解。
首先讲讲Junit环境的搭建,这个比较简单,右击你的项目--->properties-->build path--->libraries-->add Library--->Junit 再然后就是版本的选择的问题了,一般我们选择最新版,也就是4.0
在4.0之前的版本中,很多地方都采用约定的方式来进行,比如:方法命名。首先,我们来讲讲老版本的Junit测试怎么使用,你需要做三件事:
代码如下:
import junit.framework.*;
public class MyTestCase extends TestCase {
public MyTestCase(String name){
super(name);
}
}
这样,你就编写了一个测试用例,目前他还未对任何方法进行测试。我们创建它是让它来做事的对吧,可不以光吃粮不打仗。现在我们就给他找点事来做做。我们 写一个关于数学相关的类:
public class MathTool {
/**
* 求和
* @param num1
* @param num2
* @return
*/
public static int addition(int num1,int num2){
return num1+num2;
}
}
现在,我们就在MyTestCase里面来来新建一个测试方法
public void firstTest(){
assertEquals(5,MathTool.addition(2, 3));
}
我们断言,2+3 =5 ,这个时候,你右键-->run as的时候,发现有一个run as junit的选项,但是你运行以后,在下面的提示框,它却报了如下一个错:
junit.framework.AssertionFailedError: No tests found in com.amos.chapter4.MyTestCase
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.TestSuite$1.runTest(TestSuite.java:97)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
告诉你,你根本就没有具体的测试任务给它。那咋办?怎么给他交待测试任务列?你需要编写加上一个main()方法:
public static void main (String[] args) {
junit.textui.TestRunner.run (new MyTestCase("firstTest"));
}
然后右键-->run as junit,你发现下面是绿色进度条,而且提示:run 1/1 Errors:0 Failure:0。但是此时,我想,你肯定在骂娘了,这太麻烦了,写了那么多东西,最后还是要写main()方法,那还不如直接就在MathTool类里面,加上一个main()方法来进行测试。唯一的缺点就是测试代码,与业务代码耦合了,但是却可以节省不少时间。但是做程序这行,你要有这样一种心态:你永远不会是第一个发现问题的。我记得这话是老紫竹说的,所以,为了解决这个问题,就出现了一个约定:即所有的测试方法,都必须以test开头,比如:testFoo()、testBar().....好,现在我们重构一下我们的testCase,去掉main() 方法,去掉构造函数,并将firstTest()重命名成:testAddition(),代码如下:
import junit.framework.TestCase;
public class MyTestCase extends TestCase{
public void testAddition(){
assertEquals(5,MathTool.addition(2, 3));
}
}
再右键->run as junit ,哇,真的是成功了,绿色进度条。这下是不是简单了很多列?现在,你应该明白,为什么当初需要一个带参的构建函数了吧?其实就是把你要测试的方法传进去,然后junit通过反射,拿到你的方法体,帮你运行该方法,达到测试的目的。经过上面的修改以后, 那么现在你只要做2件事:
1、让你的测试用例继承至TestCase
2、让需要运行的测试方法,以test开头
关于断言语句,这是我们用的最多的,当然你也可以用自己的主要来判断是否成功。给大家列一下断言语句:
好啦,这章就讲这么多,相信大家对老版本的junit有了一个基本的了解,在接下来的一章中,将会继续讲讲老版本的一高级用法,目的也是为了后面讲新版本的同样功能的实现方式时,有一个更好的对比。