[2014-12-28]Java笔记_Junit 3.8

官网:http://junit.org/

1. 使用 Junit 的最佳实践:

        1)新建一个名为 test 的 source folder, 用于存放测试类资源代码。

        2)目标类与测试类应该位于同一个包下面,这样测试类中就不必导入源代码所在的包,因为他们位于同一个包下面。

        3)测试类的命名规则: 假如目标类是 Calculator,那么测试类应该命名为TestCalculator或者是 CalculatorTest。

2. Junit 的口号: keep the bar green to keep the code clean.

3. Junit: 单元测试不是为了证明您是对的,而是为了证明您没有错误。

4. 在junit 3.8中,测试方法需要满足如下原则:

       1.) public 的
       2.) void 的
       3.) 无方法参数
       4. )方法名称必须以test开头
       5. )测试类必须继承于TestCase 父类

5. 例子:

package com.bob.junit;

/**
 * 加减乘除类
 */

public class Calculator {

	public int add(int a, int b){
		return a + b;
	}
	
	public int subtracta(int a, int b){
		return a - b;
	}
	
	public int multiply(int a , int b){
		return a * b;
	}
	
	public int divide(int a, int b){
		return a / b;
	}
	
//	public static void main(String[] args) {
//		Calculator cal = new Calculator();
//		int result = cal.add(1, 2);
//		System.out.println("期望结果是3:" + "实际结果是:" + result);		//原始的单元测试方法
//	}
}
package com.bob.junit;

import junit.framework.Assert;
import junit.framework.TestCase;

/**
 * 测试Calculator类。
 *在junit 3.8中,测试方法需要满足如下原则:
 *1. public 的
 *2. void 的
 *3. 无方法参数
 *4. 方法名称必须以test开头
 *5. 测试类必须继承于TestCase 父类
 */

public class CalculatorTest extends TestCase {

	private Calculator cal;
	
	@Override
	public void setUp() throws Exception {		//可以扩大访问权限
		cal = new Calculator();
	}
	@Override
	protected void tearDown() throws Exception {
		// TODO Auto-generated method stub
		super.tearDown();
	}
	
	public void testAdd(){
//		Calculator cal = new Calculator();		//因为测试类包名与目标类相同所以无需导入目标类包import com.bob.junit
		
		int result = cal.add(1, 2);
		Assert.assertEquals(3, result);
	}
	
	public void testSubtract(){
//		Calculator cal = new Calculator();
		int result = cal.subtracta(1, 2);
		Assert.assertEquals(-1, result);
	}
	
	public void testMultiply(){
//		Calculator cal = new Calculator();
		int result = cal.multiply(2, 3);
		Assert.assertEquals(6, result);
	}
	
	public void testDivide(){
//		Calculator cal = new Calculator();
		int result = cal.divide(6, 2);
		Assert.assertEquals(3, result);
	}
	
//	public void testDivideDivideByZero(){
//		Calculator cal = new Calculator();
//		int result = cal.divide(6, 0);
//	}
	
}




注意:

       1) 测试用例之间一定要保持完全的独立性,不允许出现任何的依赖关系。

       2)我们不能依赖于测试方法的执行顺序

观察上面的程序会发现每行都需要 new Calculator() 对象,写代码中有一个原则:DRY(Don't Repeat Yourself),所以使用junit中提供的方法解决。

6. 关于 setUP 与 tearDown 方法的执行顺序:

      setUp  --> testAddXXX --> tearDown  以此类推。在每一个测试用例执行之前都会先执行setUp,然后执行测试方法,每一个测试用例执行之后都会执行tearDown。

7. 例子:关于异常测试的常用策略

package com.bob.junit;

/**
 * 加减乘除类
 */

public class Calculator {

	public int add(int a, int b){
		return a + b;
	}
	
	public int subtracta(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;
	}
	
//	public static void main(String[] args) {
//		Calculator cal = new Calculator();
//		int result = cal.add(1, 2);
//		System.out.println("期望结果是3:" + "实际结果是:" + result);		//原始的单元测试方法
//	}
}
package com.bob.junit;

import junit.framework.Assert;
import junit.framework.TestCase;

/**
 * 测试Calculator类。
 *在junit 3.8中,测试方法需要满足如下原则:
 *1. public 的
 *2. void 的
 *3. 无方法参数
 *4. 方法名称必须以test开头
 *5. 测试类必须继承于TestCase 父类
 */

public class CalculatorTest extends TestCase {

	private Calculator cal;
	
	@Override
	public void setUp() throws Exception {		//可以扩大访问权限
		cal = new Calculator();
	}
	@Override
	protected void tearDown() throws Exception {
		// TODO Auto-generated method stub
		super.tearDown();
	}
	
	public void testAdd(){
//		Calculator cal = new Calculator();		//因为测试类包名与目标类相同所以无需导入目标类包import com.bob.junit
		
		int result = cal.add(1, 2);
		Assert.assertEquals(3, result);
	}
	
	public void testSubtract(){
//		Calculator cal = new Calculator();
		int result = cal.subtracta(1, 2);
		Assert.assertEquals(-1, result);
	}
	
	public void testMultiply(){
//		Calculator cal = new Calculator();
		int result = cal.multiply(2, 3);
		Assert.assertEquals(6, result);
	}
	
	public void testDivide(){
//		Calculator cal = new Calculator();
		int result = 0;
		try {
			result = cal.divide(6, 2);
		} catch (Exception e) {
			e.printStackTrace();
			Assert.fail();
		}
		Assert.assertEquals(3, result);
	}
	
	public void testDivideDivideByZero(){
		Throwable tx = null;
		
		try {
			cal.divide(6, 0);	//这行代码应该需要抛异常,下面的应该不会执行
			
			Assert.fail("测试失败");		//不执行到这里才是正常的
			
		} catch (Exception ex) {
			tx = ex;	//将抛出的异常赋给异常的父类
		}
		
		Assert.assertEquals(Exception.class, tx.getClass());	//比较预期抛出的异常类型与实际类型是否相符
		Assert.assertEquals("除数不能为0", tx.getMessage());		//比较预期抛出的异常内容与实际抛出的是否相符
	}
	
}
通常情况下我们将Assert.fail(); 放在我们认为程序不可能到达的地方,如果到达了那么测试肯定是失败了。

8. 使用 Junit 原生方式运行测试用例

     1. 编写Calculator.java和CalculatorTest类;

     2. 解压缩“junit.jar” 包然后,并将解压出来的junit文件夹与编写的类放置在相同目录下(为了方便);

     3. 在测试类中加入main方法是用junit提供的“junit.textui.TestRunner.run()”或“junit.awtui.TestRunner.run()”等方法运行测试类;

     4. Win+R使用命令行方式编译运行目标类和测试类。

import junit.framework.Assert;
import junit.framework.TestCase;

/**
 * 测试Calculator类。
 *在junit 3.8中,测试方法需要满足如下原则:
 *1. public 的
 *2. void 的
 *3. 无方法参数
 *4. 方法名称必须以test开头
 *5. 测试类必须继承于TestCase 父类
 */

public class CalculatorTest extends TestCase {

	private Calculator cal;
	
	@Override
	public void setUp() throws Exception {		//可以扩大访问权限
		cal = new Calculator();
	}
	@Override
	protected void tearDown() throws Exception {
		// TODO Auto-generated method stub
		super.tearDown();
	}
	
	public void testAdd(){
//		Calculator cal = new Calculator();		//因为测试类包名与目标类相同所以无需导入目标类包import com.bob.junit
		
		int result = cal.add(1, 2);
		Assert.assertEquals(3, result);
	}
	
	public void testSubtract(){
//		Calculator cal = new Calculator();
		int result = cal.subtracta(1, 2);
		Assert.assertEquals(-1, result);
	}
	
	public void testMultiply(){
//		Calculator cal = new Calculator();
		int result = cal.multiply(2, 3);
		Assert.assertEquals(6, result);
	}
	
	public void testDivide(){
//		Calculator cal = new Calculator();
		int result = 0;
		try {
			result = cal.divide(6, 2);
		} catch (Exception e) {
			e.printStackTrace();
			Assert.fail();
		}
		Assert.assertEquals(3, result);
	}
	
	public void testDivideDivideByZero(){
		Throwable tx = null;
		
		try {
			cal.divide(6, 0);	//这行代码应该需要抛异常,下面的应该不会执行
			
			Assert.fail("测试失败");		//不执行到这里才是正常的
			
		} catch (Exception ex) {
			tx = ex;	//将抛出的异常赋给异常的父类
		}
		
		Assert.assertEquals(Exception.class, tx.getClass());	//比较预期抛出的异常类型与实际类型是否相符
		Assert.assertEquals("除数不能为0", tx.getMessage());		//比较预期抛出的异常内容与实际抛出的是否相符
	}
	
	//以Junit的方式运行测试用例
	public static void main(String[] args) {
		junit.textui.TestRunner.run(CalculatorTest.class);		//以文本命令行方式显示结果
		junit.awtui.TestRunner.run(CalculatorTest.class);		//以awt界面方式运行
	}
	
}


9.   使用反射测试类的私有方法

package com.bob.junit;

public class Calculator2 {

	private int add(int a, int b){
		return a + b;
	}
}
package com.bob.junit;

import java.lang.reflect.Method;

import junit.framework.Assert;
import junit.framework.TestCase;

//使用反射测试私有方法
public class Calculator2Test extends TestCase {

	public void testAdd() {
		Calculator2 cal2 = new Calculator2();

		Class<Calculator2> clazz = Calculator2.class;

		try {
			Method method = clazz.getDeclaredMethod("add", new Class[] {
					Integer.TYPE, Integer.TYPE });
			
			method.setAccessible(true);		//压制编译器的默认检查访问权限
			
			Object result = method.invoke(cal2, new Object[]{2, 3});
			
			Assert.assertEquals(5, result);
		} catch (Exception e) {
			Assert.fail();
		}
	}
}
10. TestSuite(测试套件):可以将多个测试组合到一起,同时执行多个测试。

package com.bob.junit;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

//自动化运行所需要的测试类
public class TestAll extends TestCase {

	//定义一个 static 的测试方法,返回一个Test对象
	public static Test suite(){
		TestSuite suite = new TestSuite();		
		
		suite.addTestSuite(CalculatorTest.class);	//添加需要执行的测试类
		suite.addTestSuite(Calculator2Test.class);
		
		return suite;
	}
}

如何运行指定方法N次:

  可以在测试类中加入带参数的构造方法,然后使用junit的RepeatedTest 类进行多次运行同一个测试方法。

	public CalculatorTest(String name){
		super(name);
	}
suite.addTest(new RepeatedTest(new CalculatorTest("testAdd"), 20));     //运行指定方法20次

11. 对于测试类来说,如果一个测试类中有5个测试方法,那么 JUnint 就会创建5个城市类的对象,每一个对象只会调用一个测试方法(为了符合命令模式的要求),在添加方法之前,需要首先判断测试方法是否满足public, void, no-arg,no-return这些条件,如果满足则添加到集合当中准备作为测试方法来去执行。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值