Java JUnit4

JUnit是一个Java语言的单元测试框架。 JUnit是由 Erich Gamma 和 Kent Beck 编写的一个 回归测试 框架(regression testing framework)。Junit测试是程序员测试,即所谓 白盒测试 ,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。


JUnit特点:
JUnit是一个开放源代码的Java测试框架,用于编写和运行可重复的测试。他是用于 单元测试框架体系xUnit的一个实例(用于java语言)。它包括以下特性:
1、用于测试期望结果的断言(Assertion)
2、用于共享共同测试数据的测试工具
3、用于方便的组织和运行测试的测试套件
4、图形和文本的测试运行器

常用于极限编程:
要求在编写代码之前先写测试,这样可以强制你在写代码之前好好的思考代码(方法)的功能和逻辑,否则编写的代码很不稳定,那么你需要同时维护测试代码和实际代码,这个工作量就会大大增加。因此在极限编程中,基本过程是这样的:构思-> 编写测试代码-> 编写代码-> 测试,而且编写测试和编写代码都是增量式的,写一点测一点,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。

编写测试代码的必要性:
不要认为压力大,就不写测试代码。相反编写测试代码会使你的压力逐渐减轻,因为通过编写测试代码,你对类的行为有了确切的认识。你会更快地编写出有效率地工作代码。
下面是一些具体的编写测试代码的技巧或较好的实践方法:
1. 不要用TestCase的 构造函数初始化Fixture,而要用setUp()和tearDown()方法。
2. 不要依赖或假定测试运行的顺序,因为JUnit利用Vector保存测试方法。所以不同的平台会按不同的顺序从Vector中取出测试方法。
3. 避免编写有副作用的TestCase。例如:如果随后的测试依赖于某些特定的交易数据,就不要提交交易数据。简单的 回滚就可以了。
4. 当继承一个测试类时,记得调用父类的setUp()和tearDown()方法。
5. 将测试代码和工作代码放在一起,一边同步编译和更新。(使用Ant中有支持junit的task.)
6. 测试类和测试方法应该有一致的命名方案。如在工作类名前加上test从而形成测试类名。
7. 确保测试与时间无关,不要依赖使用过期的数据进行测试。导致在随后的维护过程中很难重现测试。
8. 如果你编写的软件面向国际市场,编写测试时要考虑国际化的因素。不要仅用母语的Locale进行测试。
9. 尽可能地利用JUnit提供地assert/fail方法以及 异常处理的方法,可以使代码更为简洁。
10.测试要尽可能地小,执行速度快。
11.不要硬性规定数据文件的路径。
12.利用Junit 的自动异常处理书写简洁的测试代码
事实上在Junit 中使用try-catch 来捕获异常是没有必要的,Junit 会自动捕获异常。那些没有被捕获的异常就被当成错误处理。
13. 充分利用Junit 的assert/fail 方法
assertSame()用来测试两个引用是否指向同一个对象
assertEquals()用来测试两个对象是否相等
14. 确保测试代码与时间无关
15. 使用文档生成器做测试文档。
JUnit和ant结合
ant 提供了两个 target : junit 和 junitreport 运行所有 测试用例,并生成 html 格式的报表
具体操作如下:
1.将 junit.jar 放在 ANT_HOMElib 目录下
2.修改 build.xml ,加入如下 内容:
-------------- One or more tests failed, check the report for detail... -----------------------------
运行 这个 target ,ant 会运行每个 TestCase,在 report 目录下就有了 很多 TEST*.xml 和 一些网页打开 report 目录下的 index.html 就可以看到很直观的测试运行报告,一目了然。
在Eclipse中开发、运行JUnit测试相当简单。因为Eclipse本身集成了JUnit相关组件,并对JUnit的运行提供了无缝的支持。

junit4.x
(1)、使用junit4.x版本进行单元测试时,不用测试类继承TestCase父类,因为,junit4.x全面引入了Annotation来执行我们编写的测试。 [3]  
(2)、junit4.x版本,引用了注解的方式,进行单元测试;
(3)、junit4.x版本我们常用的注解:
A、@Before 注解:与junit3.x中的setUp()方法功能一样,在每个测试方法之前执行;
B、@After 注解:与junit3.x中的tearDown()方法功能一样,在每个测试方法之后执行;
C、@BeforeClass 注解:在所有方法执行之前执行;
D、@AfterClass 注解:在所有方法执行之后执行;
E、@Test(timeout = xxx) 注解:设置当前测试方法在一定时间内运行完,否则返回错误;
F、@Test(expected = Exception.class) 注解:设置被测试的方法是否有异常抛出。抛出异常类型为:Exception.class;
G、@Ignore 注解:注释掉一个测试方法或一个类,被注释的方法或类,不会被执行。

一个JUnit4的测试代码:
Calculator.java
package com.leo.calculator;

public class Calculator {
	private int x ; 
	private int y ;
	private int result ;
	
	public void setX(int ix){
		x = ix ;
	}
	
	public int getX(){
		return x ;
	}
	public void setY(int iy){
		y = iy ;
	}
	public int getY(){
		return y ;
	}
	public int getResult(){
		return result ;
	}
	
	//add
	public int add(int x, int y){
		result = x + y ;
		return result ;
	}
	
	//subtract
	public int subtract(int x, int y){
		result = x - y ;
		return result ;
	}
	
	//multiply
	public int multiply(int x, int y){
		result = x*y ;
		return result ;
	}
	
	//divide
	public double divide(int x, int y){
		double result = (double)x/y ;
		return result ;
	}

}
JUnit4的测试单元:
CalculatorTest.java
package com.leo.calculator;

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 TestCalc {
	private Calculator mycalc;

	@BeforeClass
	// 在所有方法执行之前执行
	public static void globalInit() {
		System.out.println("init all method...");
	}

	@AfterClass
	// 在所有方法执行之后执行
	public static void globalDestory() {
		System.out.println("destory all method...");
	}

	@Before
	// 在每个测试方法之前执行
	public void setUp() {
		System.out.println("start setUp method");
		mycalc = new Calculator();
	}

	@After
	// 在每个测试方法之后执行
	public void tearDown() {
		System.out.println("end tearDown method");
	}

	@Test(timeout = 600) // 设置限定测试方法的运行时间 如果超出则返回错误
	public void testAdd() {
		System.out.println("testAdd method");
		int result = mycalc.add(2, 3);
		assertEquals(5, result);
	}

	@Test
	public void testSubtract() {
		System.out.println("testSubtract method");
		int result = mycalc.subtract(1, 2);
		assertEquals(-1, result);
	}

	@Test
	public void testMultiply() {
		System.out.println("testMultiply method");
		int result = mycalc.multiply(2, 3);
		assertEquals(6, result);
	}

	@Test
	public void testDivide() {
		System.out.println("testDivide method");
		double result = 0;
		try {
			result = mycalc.divide(6, 2);
		} catch (Exception e) {
			fail();
		}
		assertEquals(3, result,0);
		/*
 assertEquals(double expected,double actul) 被废弃了(deprecated),
 换成assertEquals(double expected,double actul,double delta)
 后面加了一个误差值delta,针对于浮点数而言。
 
		 */
	}

	@Test(expected = Exception.class)
	public void testDivide2() throws Exception {
		System.out.println("testDivide2 method");
		mycalc.divide(6, 0);
		fail("test Error");
	}

	public static void main(String[] args) {
	}
}
测试结果输入如下:
界面显示输出如下:

控制台输出信息为:



控制台的输出信息与各个测试方法并不是前后对应的,可以说明,在执行各个测试方法的时候,没有严格的按照方法定义的先后执行,而是多个线程同时执行的。
但是,方法的执行顺序为:
Junit 4 的单元测试用例执行顺序为:@BeforeClass –> @Before –> @Test –> @After –> @AfterClass;
每一个测试方法的调用顺序为:@Before –> @Test –> @After。
方法的执行先后没有严格顺序。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值