单元测试
Junit
Junit目前在一些大的公司或者相对规范的软件中使用的比较多,相当多的小公司并没有把单元测试看的太重要。在大点的公司开发人员每天上班后,第一件事情就是从svn上把自己负责的代码checkout下来,然后运行单元测试,如果单元测试通过,那么说明自己的代码没有问题,然后就在代码块上修改与添加,完成后再用junit进行测试,测试完成后如果没有问题,那么就把相应的代码块提交给svn上。
单元测试的最基本的一个功能是能进行自动化测试。单元测试都是通过断言的方式来确定结果是否正确,即使用Assert。
Maven中pom.xml添加的依赖文件可以在http://mvnrepository.com/search?q=中查找
运用Maven管理下载包,在POM中添加:
1 <dependencies> 2 <dependency> 3 <groupId>junit</groupId> 4 <artifactId>junit</artifactId> 5 <version>4.12</version> 6 <scope>test</scope> 7 </dependency> 8 9 <dependency> 10 <groupId>org.hamcrest</groupId> 11 <artifactId>hamcrest-library</artifactId> 12 <version>1.3</version> 13 <scope>test</scope> 14 </dependency> 15 </dependencies>
新建一个类Calcuate,其功能主要实现加减乘除
1 public class Calcuate { 2 3 /** 4 * description:加法运算 5 * @param a 6 * @param b 7 * @return a+b 8 */ 9 public int add(int a, int b) { 10 return a + b; 11 } 12 13 /** 14 * description:减法运算 15 * @param a 16 * @param b 17 * @return a-b 18 */ 19 public int minus(int a, int b) { 20 return a - b; 21 } 22 23 /** 24 * description:除法运算 25 * @param a 26 * @param b 27 * @return a/b 28 */ 29 public int divide(int a, int b) { 30 return a / b; 31 } 32 33 /** 34 * description:乘法运算 35 * @param a 36 * @param b 37 * @return 38 */ 39 public int mul(int a, int b) { 40 return a * b; 41 }
选中测试包,右键-》新建Junit Test Case ;
junit3与junit4的区别还是比较明显的,在junit3中,如果某个类是测试类,必须将其继承类TestCase,如果某个方法是测试方法,必须让这个方法以testXX开头,如果希望指定某个测试方法运行之前运行某个初始化方法,这个方法的名称必须是setUp,如果希望在某个测试方法运行之后运行某个释放资源的方法,这个方法的名称必须是tearDown。
在junit4中,一个POJO类就是一个测试类,测试方法通过@Test来标识,初始化方法通过@Before来标识,释放资源的方法通过@After来标识,但是为了让junit4的测试类在junit3中也可以使用,习惯于把初始化方法命名为setUp,释放资源的方法命名为tearDown。Test中的测试方法一般以Test来开始。其中标识为Before注解的方法,每次运行测试类,都会执行标识为@After与@Before的方法。
1 public class TestCalcuate { 2 3 Calcuate cal; 4 5 @Before 6 public void setUp() throws Exception { 7 cal = new Calcuate(); 8 } 9 10 11 @After 12 public void tearDown() throws Exception { 13 } 14 15 @Test 16 public void testAdd() { 17 int rel = cal.add(1, 2); 18 Assert.assertEquals("加法有问题", rel, 3); 19 } 20 21 @Test 22 public void testMinus(){ 23 int rel = cal.minus(3, 1); 24 Assert.assertEquals("减法有问题", rel,2); 25 } 26 27 @Test 28 public void testDivide(){ 29 int rel = cal.divide(10, 1); 30 Assert.assertEquals("除法有问题", rel, 9); 31 }
在junit4中提供了一个Assert的类,这个类中有大量的静态方法进行断言的处理,在junit3中由于继承了TestCase,这个TestCase就可以直接assert,而junit4中需要先引入Assert类。
在上图中使用了Assert类中的assertEquals方法,这方法的第一个参数意思是:如果方法cal.Add(1,2)计算的结果不为3,那么就会打印出“加法有问题”的信息。第二个参数为方法cal.Add(1,2)的执行结果,第三个参数是开发人员预计的函数cal.Add(1,2)执行后的结果。
使用junit测试比使用main方法测试有很大的不同的,每个标识为@Test的方法都是一个可运行的方法,并且他们之间互不影响,例如testAddd方法出现问题了,并不影响testMinus方法的运行,这就是单元测试的好处。
在测试除法cal.divide(10,0),如果除数为0,这个方法应该会抛出异常。现在的测试目标是,如果运行测试方法,测试方法没有抛出异常,那么这个测试方法就不能通过。这时就需要用到junit的ArithmeticException。
这里如果把cal.divide(10,0)改成cal.divide(10,1),这样divide是没有问题的,但是这时测试类中的testDivideException方法执行junit测试后就不能通过了,因为这个测试方法已经断言所要测试的方法divide要抛出异常,结果没有抛出异常,所以junit测试是不能通过的。
Junit的最基本的东西是这样的,断言、测试异常,捕获异常,测试方法的性能。
hamcrest
很多时候使用assert做判断,并不方便,如果要判断某几个值是否为true或false,这时使用hamcrest来判断就会方便许多。hamcrest就是专门为增强junit来提供的框架。
如果出现以下错误:
其原因是因为资源路径里junit的jar包在hamcrest的jar包上面,java运行环境先从junit包中查找allOf方法,但是这里使用的是hamcrest的allOf方法。从资源路径里把两个包的路径换一下就可以了。如下图,选择hamcrest的jar包点击up,就可以反hamcrest的jar包放在junit的jar包的上面,java运行环境就会优先从hamcrest包中查allOf方法。
TestSuite
在一个项目中,可能有很多的测试类,如果每个测试类都要点击运行,那么成百上千个类都需要测试,这会是个比较繁重的工作,这时可以使用可以使用junit的jar包中提供的Suite来解决这个问题,上面的例子中只有一个测试类名叫TestCalcuate,现在新建两个测试类,分别为testA、testB
然后新建一个测试类TestSuite,这个类可以把以上三个类,testCalcuate、testA、testB,这三个测试方法同事进行测试。
@RunWith(Suite.class) //代表以Suite来运行这个测试类
@SuiteClasses({testA.class,testB.class,testCalcuate.class}) //代表要测试的类有哪些
注意:
1.建议创建一个专门的source folder--->test来编写测试类代码。
2.测试类的包应该保持和需要测试的类一致。
3.测试单元中的每个测试方法都必须可以独立执行,不相互依赖。