转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/45281449
前言
好久没有写来CSDN写博客了,前段时间一直在加班赶项目,所以博客一直没有更新;现在空闲时间比较多,所以后面会长期更新博客。
今天来复习一下单元测试基于Junit工具的使用。Junit3.8与Junit4.x的使用还是有些区别的,所以分开来讲,但不管怎样,单元测试的目的并不是证明你是对的,而是为了证明你没有错误,同时也为提高程序健壮性、可重用测试、降低代码后期维护等提供了很好的支持和帮助。
(一) 基于Junit3.8的实例说明
/**
* 基本四则运算 -- 目标类
*
* @author [*昨日重现*] [email protected]
* @since version 1.0
* @datetime 2015年4月24日 上午10:35:13
*/
public class Calculator {
private int add(int num1, int num2) {
return num1 + num2;
}
public int subtract(int num1, int num2) {
return num1 - num2;
}
public int multiply(int num1, int num2) {
return num1 * num2;
}
public int divide(int num1, int num2) {
if (num2 == 0) {
throw new ArithmeticException("除数不能为0");
}
return num1 / num2;
}
}
基于Junit3.8的测试类
/**
* 基于Junit3.8
*
* 测试源代码中的目标类,测试类必须继承TestCase
*
* @author [*昨日重现*] [email protected]
* @since version 1.0
* @datetime 2015年4月24日 上午10:43:22
*/
public class CalculatorTest extends TestCase {
private Calculator cal = null;
@Override
protected void setUp() throws Exception {
// TODO Auto-generated method stub
super.setUp();
// 每个测试方法执行前,重新new一个对象,避免测试用例之间的依赖
cal = new Calculator();
System.out.println("在每个测试方法执行前执行--setUp...");
}
/**
* 测试源代码的私有方法
*/
public void testAdd() {
System.out.println("测试方法testAdd...");
// Assert.assertEquals(3, cal.add(1, 2));// blue bar
try {
// 1、getClass;2、Class.forName(); 3、.class
Class calzz = Calculator.class;
// Class> calzz = Class.forName("com.leo.junit.Calculator");
// Calculator cal = calzz.newInstance();
Method method = calzz.getDeclaredMethod("add", new Class[] {
Integer.TYPE, Integer.TYPE });// 后两个参数为:方法名、参数类型
method.setAccessible(true);// 设置为可访问私有的add方法
// 后两个参数为:目标类对象、实参对象;返回目标方法的结果
Object obj = method.invoke(cal, new Object[] { 1, 2 });
Assert.assertEquals(3, obj);
} catch (Exception e) {
// e.printStackTrace();
Assert.fail();
}
}
public void testSubstrub() {
System.out.println("测试方法testSubstrub...");
Assert.assertEquals(3, cal.subtract(1, 2));// red bar,failure 说明测试没有通过(失败)
}
public void testMultiply() {
System.out.println("测试方法testMultiply...");
Assert.assertEquals(2, cal.multiply(1, 2));// blue bar
}
public void testDivide() {
System.out.println("测试方法testDivide...");
Assert.assertEquals(2, cal.divide(1, 0));// red bar, error 说明测试程序本身出错
}
@Override
protected void tearDown() throws Exception {
// TODO Auto-generated method stub
super.tearDown();
// cal = null;// 在每个测试方法执行后主动销毁对象
System.out.println("在每个测试方法执行后执行--tearDown...\n");
}
// public static void main(String[] args) {
// junit.textui.TestRunner.run(CalculatorTest.class);// 控制台打印错误日志
// }
}
注意事项:
1)Junit的原则:keep the bar green to keep the code clean。2)测试类与(源代码)目标类的包名尽量要一致,最终它们都会被编译到同一个目录下面,这样就不用导入源代码所在的包。
3) 测试类的命名规则:测试类类名 = 目标类类名前或后加Test; 注意要统一。
4) 测试类必须继承TestCase; 测试用例(方法/类)与测试用例之间一定是完全独立的,不允许出现任何的依赖关系。同时也不能依赖测试方法的执行顺序,也就是删除或注释掉某个测试方法后,其他的测试方法依然能够执行。
5) 测试源代码的私有方法可以采取两种方式:1、修改目标方法的访问修饰符(将private修改为public,一般不推荐);2、使用反射在测试类中调用目标类的私有方法。
(二)基于Junit4.x的实例说明
/**
* 基于Junit4.X --主要基于注解Annotation
*
* @author [*昨日重现*] [email protected]
* @since version 1.0
* @datetime 2015年4月25日 上午12:06:52
*/
// @Ignore 将忽略掉该类的所有测试方法
public class CalculatorTest2 {
private Calculator cal = null;
@BeforeClass
public static void beforeClass() {
System.out.println("=========在所有测试方法执行前执行--beforeClass=====\n");
}
/**
* 在测试方法执行完前执行
*/
@Before
public void beforeMethod() {
System.out.println("在每个测试方法执行前执行--beforeMethod...");
cal = new Calculator();
}
// 若超时1s,将报error错误
@Test(timeout = 1000)
// 若期待有异常抛出:expected = Exception.class
public void testSubstrub() // throws Exception
{
System.out.println("测试方法testSubstrub被执行...");
Assert.assertEquals(-1, cal.subtract(1, 2));
// Assert.assertEquals(-1, cal.divide(1, 0));
}
@Test
@Ignore("该testMultiply测试方法由于XX原因需要被忽略掉")
public void testMultiply() {
System.out.println("测试方法testMultiply被执行...");
Assert.assertEquals(2, cal.multiply(1, 2));
}
/**
* assertThat及Hamcrest的基本使用
*/
@Test
public void testOther() {
int result = cal.subtract(1, 2);
// 关于字符串
String s1 = "leo";
org.junit.Assert.assertThat(result, Matchers.is(-1));
org.junit.Assert.assertThat(s1, Matchers.not("llleo"));
// org.junit.Assert.assertThat(s1, Matchers.equalToIgnoringCase("LeO"));
// org.junit.Assert.assertThat(s1,
// Matchers.equalToIgnoringWhiteSpace(" Leo "));
// org.junit.Assert.assertThat(s1, Matchers.containsString("leo"));
// org.junit.Assert.assertThat(s1, Matchers.startsWith("le"));
// org.junit.Assert.assertThat(s1, Matchers.endsWith("o"));
// org.junit.Assert.assertThat(s1, Matchers.equalTo("leo"));
// 关于基本类型
double d1 = 3.1;
// 在3.0±0.2之间
org.junit.Assert.assertThat(d1, Matchers.closeTo(3.0, 0.2));
// 大于3.0
org.junit.Assert.assertThat(d1, Matchers.greaterThan(3.0));
// 小于4.0
org.junit.Assert.assertThat(d1, Matchers.lessThan(4.0));
// 大于或等于3.0
org.junit.Assert.assertThat(d1, Matchers.greaterThanOrEqualTo(3.0));
// 小于或等于4.0
org.junit.Assert.assertThat(d1, Matchers.lessThanOrEqualTo(4.0));
// 关于集合
Map map = new HashMap();
map.put("k1", "zhangsan");
map.put("k2", "lisi");
// 是否含有该k1=zhangsan的键值对
org.junit.Assert.assertThat(map, Matchers.hasEntry("k1", "zhangsan"));
// 是否含有键为k2的Item
org.junit.Assert.assertThat(map, Matchers.hasKey("k2"));
// 是否含有值为lisi的Item
org.junit.Assert.assertThat(map, Matchers.hasValue("lisi"));
}
/**
* 在测试方法执行完后执行
*/
@After
public void afterMethod() {
// cal = null;// 在每个测试方法执行后主动销毁对象
System.out.println("在每个测试方法执行后执行--afterMethod...\n");
}
@AfterClass
public static void afterClass() {
System.out.println("=========在所有测试方法执行后执行--afterClass=====");
}
}
注意事项:
1)在一个测试类中,所有被@Test注解所修饰的public void方法都是测试用例,可以被JUnit所执行。
2) failure是指测试失败,而error是指测试程序本身出错。
结束语
明天开始续《Java学习系列》,包括反射、注解、内部类等等。