`

Java学习系列(二十五)基于Junit3.8和Junit4.x的单元测试详解

 
阅读更多

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/45281449

前言

 

好久没有写来CSDN写博客了,前段时间一直在加班赶项目,所以博客一直没有更新;现在空闲时间比较多,所以后面会长期更新博客。
今天来复习一下单元测试基于Junit工具的使用。Junit3.8与Junit4.x的使用还是有些区别的,所以分开来讲,但不管怎样,单元测试的目的并不是证明你是对的,而是为了证明你没有错误,同时也为提高程序健壮性、可重用测试、降低代码后期维护等提供了很好的支持和帮助。

(一) 基于Junit3.8的实例说明

 

/**
 * 基本四则运算 -- 目标类
 * 
 * @author [*昨日重现*] lhy_ycu@163.com
 * @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 [*昨日重现*] lhy_ycu@163.com
 * @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<Calculator> 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 [*昨日重现*] lhy_ycu@163.com
 * @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<String, String> map = new HashMap<String, String>();
		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学习系列》,包括反射、注解、内部类等等。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics