JUnit是一个开发源代码的Java测试框架,用于编写和运行可重复的测试。
JUnit最初是由Erich Gamma(GoF之一)和Kent Beck(xp和refactor的先驱之一)编写的,需要说明的是JUnit一般是用来进行单元测试的,因此需要了解被测试代码的内部结构(即所谓的白盒测试),另外junit是在xp编程和重构(refactor)中被极力推荐使用的工具,因为在实现自动单元测试的情况下可以大大的提高开发的效率。
Junit提供了assert断言方法
以一个简单的例子来介绍Junit3和Junit4
待测试类:
package com.test.junit;
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int minus(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
public int divide(int a, int b) throws Exception {
if(0 == b) {
throw new Exception("除数不能为0");
}
return a / b;
}
}
通过Junit3进行测试
在通过JUnit3.x构建测试时,必须要继承TestCase这个类。同时在构建测试方法时要遵循以下原则:
- 测试方法应该是public
- 测试方法无返回值
- 测试方法无参数
- 测试方法名称必须以test开头(以便反射机制生成测试方法)
package com.test.junit;
import junit.framework.TestCase;
public class TestCalculator4JUnit3 extends TestCase {
private Calculator calculator;
protected void setUp() throws Exception {
System.out.println("---setUp---");
calculator = new Calculator();
}
protected void tearDown() throws Exception {
System.out.println("---tearDown---");
}
public void testAdd() {
assertEquals(9, calculator.add(4, 5));
System.out.println("---testAdd---");
}
public void testMinus() {
assertEquals(-1, calculator.minus(4, 5));
System.out.println("---testMinus---");
}
public void testMultiply() {
assertEquals(20, calculator.multiply(4, 5));
System.out.println("---testMultiply---");
}
public void testDivide() {
try {
assertEquals(0, calculator.divide(4, 5));
System.out.println("---testDivide---");
} catch (Exception e) {
e.printStackTrace();
}
}
}
执行之后结果:
---setUp---
---testMultiply---
---tearDown---
---setUp---
---testDivide---
---tearDown---
---setUp---
---testMinus---
---tearDown---
---setUp---
---testAdd---
---tearDown---
通过运行结果我们可以看出:
- setUp()和tearDown()方法在每个测试方法执行前和后都会执行一次,而不是这个测试只执行一次
- 测试方法的顺序是随机的
- 对于抛出异常的方法在测试方法中要进行相关的处理
通过JUnit4进行测试
使用junit4.x版本进行单元测试时,测试类不必继承TestCase父类,因为,junit4.x全面引入了Annotation(注解)来执行测试。
junit4.x版本常用的注解:
- @Before 注解:初始化方法,对于每一个测试方法都要执行一次;与junit3.x中的setUp()方法功能一样,在每个测试方法之前执行
- @After 注解:释放资源,对于每一个测试方法都要执行一次;与junit3.x中的tearDown()方法功能一样,在每个测试方法之后执行
- @BeforeClass 注解:在所有方法执行之前执行,针对所有测试,只执行一次,且必须为static void
- @AfterClass 注解:在所有方法执行之后执行,针对所有测试,只执行一次,且必须为static void
- @Test(timeout = xxx) 注解:设置当前测试方法在一定时间内运行完,否则返回错误
- @Test(expected = Exception.class) 注解:设置被测试的方法是否有异常抛出。抛出异常类型为:Exception.class
- @Ignore 注解:注释掉一个测试方法或一个类,被注释的方法或类,不会被执行
package com.test.junit;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestCalculator4JUnit4 {
private static Calculator calculator;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("---setUpBeforeClass---");
calculator = new Calculator();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("---tearDownAfterClass---");
}
@Before
public void setUp() throws Exception {
System.out.println("---setUp---");
}
@After
public void tearDown() throws Exception {
System.out.println("---tearDown---");
}
@Test
public void testAdd() {
assertEquals(9, calculator.add(4, 5));
System.out.println("---testAdd---");
}
@Test
public void testMinus() {
assertEquals(-1, calculator.minus(4, 5));
System.out.println("---testMinus---");
}
@Test
public void testMultiply() {
assertEquals(20, calculator.multiply(4, 5));
System.out.println("---testMultiply---");
}
@Test(expected=Exception.class)
public void testDivide() throws Exception {
assertEquals(0, calculator.divide(4, 0));
System.out.println("---testDivide---");
}
}
测试结果:
---setUpBeforeClass---
---setUp---
---testMinus---
---tearDown---
---setUp---
---testMultiply---
---tearDown---
---setUp---
---tearDown---
---setUp---
---testAdd---
---tearDown---
---tearDownAfterClass---
在testDivide()方法中抛出异常,但是抛出的异常与我们在@Test(expected=Exceptopn.class)相同,所以也不会抛出异常提示。
运行结果与测试类顺序无关。
JUnit3.x与JUnit4.x区别
- JUnit3必须继承TestCase这个类,而在JUnit4中则不需要继承任何类
- JUnit3中的测试方法必须以test开头,形式为testXXX();而在JUnit4中则不必以test开头,但是测试方法必须加上@Test注解
- 在JUnit3中需要覆盖TestCase中的setUp和tearDown方法,其中setUp方法会在测试执行前被调用以完成初始化工作,而tearDown方法则在结束测试结果时被调用,用于释放测试使用中的资源,而在JUnit4中,只需要在方法前加上@Before 以及 @After即可,其名字也可以任意取。被@BeforeClass 和 @AfterClass注解的方法的命名必须是public static void *(),针对所有测试,只执行一次
- 增加了新的断言assertThat
- 测试的异常处理Junit4.x增加了@Test(expected=Exception.class)
- Junit4.x增加了@Test(timeout = xxx) 注解和@Ignore 注解