`

JUnit 3.8.2和JUnit 4.8.1学习笔记

阅读更多

 

JUnit学习笔记 2011年10月01日 环境 MyEclipse 9.0


铺垫:

 

1、单元测试(Unit Test): 

 

 是针对软件的最小模块进行正确性检验的测试工作。
 所谓最小模块,在OOP的范畴内,通常是指对象的方法。

 

2、为什么要做单元测试?

 

 进行单元测试是降低软件风险和减少维护成本的有效途径。

 

3、以前是怎么做测试的?

 

 main方法、sysout输出……

 

 优点: 快速直接

 

 缺点: 没有留下可重用的代码。
           无法进行自动化回归测试。
           增加了类的体积,代码不清晰。
           不规范、不优雅。

 

4、断言(Assertion):

 

 在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。
 在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,
 一个正确程序必须保证这个boolean表达式的值为true;
 如果该值为false,说明程序已经处于不正确的状态下,assert将给出警告或退出。
 一般来说,assertion用于保证程序最基本、关键的正确性。
 assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。


/*************************************************************************************************
 * 需补充关键词:
 * ① 测试驱动开发(TDD: Test-Driven Development)
 * ② Hamcrest(JUnit4.4后引入的测试框架提供了一套匹配符,可结合使用全新的断言语法:assertThat)
 ************************************************************************************************/

 


---------------------------------------我是华丽的分割线-------------------------------------------

 


正题:

 

一、JUnit简介

 

JUnit是基于面向对象构建的java单元测试框架。
JUnit是开放源代码项目,可按需要进行扩展,操作相对简单。
JUnit官方网站:http://www.junit.org
JUnit的口号:keep the bar green to keep the code clean。(PS:口号的具体含义用过JUnit后就知道了……)

 

目前JUnit官网最新版本是4.10。

我用的MyEclipse 9.0内置了3.8.2和4.8.1。

 

3.X和4.X两个版本最主要的区别是:

 

 JUnit3基于继承
 JUnit4基于注解

 

两种未通过测试的结果:
 
 Failure: 测试失败
 Error:  异常错误


二、JUnit应用

 

 

    待测类之一:

/**
 * @author Maxpin on 2011-10-01 含有四则运算方法的普通类
 */
public class Calc {
	/**
	 * 加法
	 * 
	 * @param x
	 *            数x
	 * @param y
	 *            数y
	 * @return 和
	 */
	public int add(int x, int y) {
		return x + y;
	}

	/**
	 * 减法(私有方法)
	 * 
	 * @param x
	 *            数x
	 * @param y
	 *            数y
	 * @return 差
	 */
	@SuppressWarnings("unused")
	private int subtract(int x, int y) {
		return x - y;
	}

	/**
	 * 乘法
	 * 
	 * @param x
	 *            数x
	 * @param y
	 *            数y
	 * @return 积
	 */
	public int multiply(int x, int y) {
		return x * y;
	}

	/**
	 * 除法
	 * 
	 * @param x
	 *            数x
	 * @param y
	 *            数y
	 * @return 商
	 * @throws Exception
	 *             抛出异常
	 */
	public int divide(int x, int y) throws Exception {
		if (0 == y) {
			throw new Exception("除数不能为0");
		}
		return x / y;
	}
}

 

 

1、使用JUnit 3.8.2的操作步骤及注意事项:

 

 1)为项目导入JUnit的jar包(Build path → Add Library → JUnit)。
 2)新建一个名为test的Source Folder,用于存放测试类源代码。
 3)目标类与测试类应该位于同一个包下面,这样测试类中就不必导入源代码所在的包,因为他们位于同一个包下面。
 4)测试类的命名规则:假如目标类是Calc,那么测试类应该命名为TestCalc或者是CalcTest。
 5)测试类必须要继承于TestCase父类。
 6)测试方法必须要满足public void修饰、无方法参数、方法名必须以test开头。
 7)重写setUp()方法和tearDown()方法以便于对测试数据的初始化和回归操作。
 8)执行顺序:setUp(测试方法之前)、testMethod(执行的测试方法)、tearDown(测试方法之后)。
 9)为了测试私有方法,可以使用反射机制。
 10)TestSuite(测试套件):可以将多个测试组合到一起,同时执行多个测试。

 

/**
 * 
 * @author Maxpin on 2011-10-01 含有四则运算方法的测试类
 * 
 */
public class CalcTest extends TestCase {

	private Calc calc;

	@Override
	protected void setUp() throws Exception {
		calc = new Calc();
	}

	@Override
	protected void tearDown() throws Exception {
		System.out.println("tearDown invoked");
	}

	/**
	 * 测试加法
	 */
	public void testAdd() {
		int result = calc.add(1, 2);
		assertEquals(3, result);
		System.out.println("加法测试完毕");
	}

	/**
	 * 测试减法(通过反射测试私有方法)
	 */
	public void testSubtract() {
		Class<Calc> clazz = Calc.class;
		try {
			Method method = clazz.getDeclaredMethod("subtract", new Class[] {
					Integer.TYPE, Integer.TYPE });
			// 关闭安全检查
			method.setAccessible(true);
			Object result = method.invoke(calc, new Object[] { 2, 3 });
			assertEquals(-1, result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("减法测试完毕");
	}

	/**
	 * 测试除法
	 */
	public void testDivide() {
		Throwable th = null;
		int result = 0;
		try {
			result = calc.divide(10, 5);
		} catch (Exception e) {
			th = e;
			fail("测试失败");
		}
		assertNull(th);
		assertEquals(2, result);
		System.out.println("除法测试完毕");
	}

	/**
	 * 测试除法(期望报异常)
	 */
	public void testDivideByZero() {
		Throwable th = null;
		try {
			@SuppressWarnings("unused")
			int result = calc.divide(10, 0);
			fail("测试失败");
		} catch (Exception e) {
			th = e;
		}
		assertNotNull(th);
		assertEquals(Exception.class, th.getClass());
		assertEquals("除数不能为0", th.getMessage());
		System.out.println("除法异常测试完毕");
	}

}


/**
 * 
 * @author Maxpin on 2011-10-01 删除目录方法的测试类
 * 
 */
public class DeleteAllTest extends TestCase {
	public DeleteAllTest() {
	}

	/**
	 * 用于重复测试指定方法、指定次数时使用的构造方法
	 * 
	 * @param name
	 *            方法名
	 */
	public DeleteAllTest(String name) {
		super(name);
	}

	/**
  	* 测试删除目录的方法
  	* 构造测试数据,目录结构:
  	*       	---dir---
  	*      	   /   |    \
  	*     	 /    |     \
  	*     	 /     |      \
  	*     	/      |       \
  	*  subFile1 subFile2 file1.txt
  	*       /
  	*      /
  	*  file2.txt
  	*/	 
	public void testDeleteAll() {
		File directory = null;
		try {
			//主文件夹
			directory = new File("dir");
			directory.mkdir();
			//子文件夹1
			File subFile1 = new File(directory, "subFile1");
			//子文件夹2
			File subFile2 = new File(directory, "subFile2");
			subFile1.mkdir();
			subFile2.mkdir();
			//主文件夹下的文件
			File file1 = new File(directory, "file1.txt");
			file1.createNewFile();
			//子文件夹1下的子文件
			File file2 = new File(subFile1, "file2.txt");
			file2.createNewFile();
			DeleteAll.deleteAll(directory);
		} catch (Exception ex) {
			Assert.fail();
		}
		Assert.assertNotNull(directory);
		String[] names = directory.list();
		Assert.assertEquals(0, names.length);
		directory.delete();
		System.out.println("I/O流删除目录测试完毕");
	}
}


/**
 * 
 * @author Maxpin on 2011-10-01 测试套件类
 * 
 */
public class TestAll extends TestCase {
	/**
	 * 定义测试集
	 * 
	 * @return
	 */
	public static Test suite() {
		TestSuite suite = new TestSuite();
		// 四则运算
		suite.addTestSuite(CalcTest.class);
		// 只乘法
		suite.addTestSuite(CalcTest2.class);
		// 删除目录
		suite.addTest(new RepeatedTest(new DeleteAllTest("testDeleteAll"), 20));
		return suite;
	}
}

 

2、使用JUnit 4.8.1的操作步骤及注意事项:

 

 1)为项目导入JUnit的jar包(Build path → Add Library → JUnit)。
 2)新建一个名为test的Source Folder,用于存放测试类源代码。
 3)目标类与测试类应该位于同一个包下面,这样测试类中就不必导入源代码所在的包,因为他们位于同一个包下面。
 4)JUnit4并不要求测试类继承TestCase父类。
 5)在一个测试类中,所有被 @Test 注解所修饰的public void方法都是TestCase(测试用例),可以被JUnit所执行。
 6)规范:虽然JUnit 4并不要求测试方法名以test开头,
   但最好还是按照JUnit 3.8.2的要求那样,以test作为测试方法名的开头。
 7)在JUnit4中,通过 @Before 注解实现与JUnit 3.8.2中的setUp方法同样的功能,
    通过 @After 注解实现与JUnit 3.8中的tearDown方法同样的功能。
 8)在JUnit4中,可以使用 @BeforeClass与 @AfterClass注解修饰一个public static void  no-arg 的方法,
    这样被 @BeforeClass注解所修饰的方法会在所有测试方法执行前执行;
    被 @AfterClass注解所修饰的方法会在所有测试方法执行之后执行。
 9)注解 @Ignore可用于修饰测试类与测试方法,当修饰测试类时,表示忽略掉类中的所有测试方法;
    当修饰测试方法时,表示忽略掉该测试方法。
 10)参数化测试(Parameters):当一个测试类使用参数化运行器运行时,
     需要在类的声明处加上 @RunWith(Parameterized.class)注解,表示该类将不使用JUnit内建的运行器运行,
     而使用参数化运行器运行;在参数化运行类中提供参数的方法上要使用 @Parameters注解来修饰,
     同时在测试类的构造方法中为各个参数赋值(构造方法是由JUnit 调用的),
     最后编写测试类,它会根据参数的组数来运行测试多次。
 11)在JUnit4中,如果想要同时运行多个测试,需要使用两个注解:
     @RunWith(Suite.class)以及 @Suite.SuiteClasses(),通过这两个注解分别指定使用Suite运行器来运行测试,
     以及指定了运行哪些测试类,其中的 @SuiteClasses中可以继续指定Suite,这样JUnit会再去寻找里面的测试类,
     一直找到能够执行的TestCase并执行之。
 12)JUnit4中可以使用JUnit3的方法进行测试,而不使用注解机制,即JUnit3可以完美升级至JUnit4,但4更灵活、方便。


 

/**
 * @author Maxpin on 2011-10-01 含有四则运算方法的测试类
 * 
 */
public class CalcTest {

	private Calc calc;

	//在所有测试方法前执行一次
	@BeforeClass
	public static void globalInit() {
		System.out.println("globalInit invoked");
	}

	//在所有测试方法后执行一次
	@AfterClass
	public static void globalDestroy() {
		System.out.println("globalDestroy invoked");
	}

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

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

	// 测试方法执行超过1000毫秒后算超时,测试将失败
	@Test(timeout = 1000)
	public void testAdd() {
		calc = new Calc();
		int result = calc.add(1, 2);
		assertEquals(3, result);
	}

	// 测试方法期望得到的异常类
	@Test(expected = Exception.class)
	public void testDivide() throws Exception {
		calc.divide(1, 0);
	}

	// 执行测试时将忽略掉此方法,如果用于修饰类,则忽略整个类
	@Ignore("not ready yet")
	@Test
	public void testSubtract() {
		calc = new Calc();
		int result = calc.subtract(1, 2);
		assertEquals(-1, result);
	}
}


/**
 * @author Maxpin on 2011-10-01 多组参数值测试加法运算的测试类
 * 
 *         使用参数化运行器运行
 */
@RunWith(Parameterized.class)
public class CalcParametersTest {

	Calc clac;

	private int expected; // 期望值
	private int input1; // 输入值1
	private int input2; // 输入值2

	@SuppressWarnings("rawtypes")
	// 提供参数的方法
	@Parameters
	public static Collection preparedData() {
		Object[][] obj = { { 3, 1, 2 }, { 0, -5, 5 }, { 10, 8, 2 } };
		return Arrays.asList(obj);
	}

	/**
	 * 带参构造方法
	 * 
	 * @param expected
	 *            参数期望值
	 * @param input1
	 *            参数输入值1
	 * @param input2
	 *            参数输入值2
	 */
	public CalcParametersTest(int expected, int input1, int input2) {
		this.expected = expected;
		this.input1 = input1;
		this.input2 = input2;
	}

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		clac = new Calc();
	}

	/**
	 * Test method for {@link com.accp.junit4.Calc#add(int, int)}.
	 */
	@Test
	public void testAdd() {
		// 直接断言,会根据参数的组数来执行测试多次
		assertEquals(this.expected, clac.add(this.input1, this.input2));
	}

}


/**
 * 
 * @author Maxpin on 2011-10-01 套件测试类
 * 
 *         测试套件
 * 
 *         使用Suite运行器测试,并指定测试类
 */
@RunWith(Suite.class)
@Suite.SuiteClasses({ CalcTest.class, CalcParametersTest.class })
public class TestAll {

}


/**
 * 
 * @author Maxpin on 2011-10-01 套件测试类
 * 
 *         测试套件
 * 
 *         使用Suite运行器测试也可以嵌套Suite
 */
@RunWith(Suite.class)
@Suite.SuiteClasses({ TestAll.class, LargestorTest.class })
public class TestAllTest {

}

 


---------------------------------------我是华丽的分割线-------------------------------------------


总结:

 

 JUnit单元测试框架体积小巧,功能强大。
 及时测试显然是一种良好的开发习惯,即便测试代码量多过于被测代码量。。。
 JUnit3和JUnit4相比较而言,后者更加灵活便利。
 测试代码执行前后,被测代码的状态始终应保持一致性。


 引用某名言:单元测试不是为了证明您是对的,而是为了证明您没有错误。

 

 

 最后:附上完整版的练习实例源码,仅供学习参考交流使用。

分享到:
评论
1 楼 peng860226327 2015-01-13  

相关推荐

    junit3.8.2.zip

    这个"junit3.8.2.zip"压缩包包含了JUnit 3.8.2的所有相关资源,方便开发者在项目中集成和使用。 JUnit 3.8.2主要知识点包括: 1. **测试注解**:虽然在后续的JUnit版本中注解功能得到了进一步加强,但在3.8.2中,`...

    junit3.8.2

    junit3.8.2junit3.8.2junit3.8.2junit3.8.2junit3.8.2

    junit3.8.2 jar包和源码

    1. **添加依赖**: 在项目中,需要将junit3.8.2.jar添加到类路径,以便编译和运行测试。在IDE如Eclipse中,这可以通过右键点击项目 -&gt; Build Path -&gt; Configure Build Path -&gt; Libraries -&gt; Add Jars 或 Add External...

    junit3.8.2 chm帮助文档

    在"junit3.8.2 chm帮助文档"中,你可以找到关于JUnit 3.8.2的详尽指南和API文档。以下是该文档可能涵盖的一些关键知识点: 1. **JUnit简介**:解释了什么是JUnit,其目标和用途,以及如何在项目中引入JUnit库。 2....

    Junit 3.8.2

    对于更复杂的测试场景,JUnit 3.8.2提供了`@BeforeClass`和`@AfterClass`注解,这两个方法在整个测试类中只运行一次,分别在所有测试之前和之后执行,适合处理一次性的设置和清理任务。 在实际使用中,我们可以通过...

    junit-3.8.2.jar.zip114k.zip

    《JUnit 3.8.2:经典单元测试框架的基石》 ...虽然现在JUnit已经有了更新的版本,但3.8.2仍然是许多遗留项目和教学环境中常用的版本,它的设计思想和基本功能对理解单元测试和持续集成的重要性具有深远的影响。

    junit-3.8.2.jar

    JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中为最成功的一个。

    junit3.8.2.chm

    使用了javadocchm制作的juint帮助文档。。。。

    JUnit4.8.1源码包

    JUnit4.8.1源码包 版本4.8.1 只有源码。

    junit4.8.1.jar

    9. **规则(Rules)**:JUnit 4.8.1引入了测试规则,如`ExternalResource`和`ExpectedException`,这些规则在测试前后执行特定的行为。 10. **Hamcrest匹配器**:JUnit 4集成了Hamcrest库,提供了一套丰富的匹配器...

    JUnit3.X和4.X学习记录及用例

    本资源包含了JUnit3.8.2和JUnit4.8.1两个版本的学习笔记和练习用例,帮助我们深入理解这两个版本的差异与特性。 首先,JUnit3.8.2是JUnit系列的一个较早版本,其核心概念包括断言(Assertions)、测试方法(Test ...

    Junit4.8.1.rar

    同时,还包括了源码,这对于学习和理解JUnit的工作原理以及自定义扩展非常有帮助。 JUnit4引入了一些关键特性,如注解(Annotations)和参数化测试,极大地提高了测试的灵活性和可读性。例如,`@Test`注解用于标记...

    junit4.8.1

    JUnit 4.8.1在4.x系列中提供了许多改进和新特性,旨在提升测试的效率和灵活性。 1. **注解驱动测试**:JUnit 4引入了注解(Annotation)的概念,使得测试类和方法的声明更加简洁。例如,`@Test`注解用于标记测试...

    junit.4.8.1.jar

    junit.4.8.1.jar ,xstream实例见http://download.csdn.net/detail/jnsunw/3750332

    Junit学习笔记~

    Junit学习笔记,希望有用~~~~~~~~~~~~~~~~~~~~~~

    junit4.8.1 单元测试 完整压缩包

    压缩包文件"junit4.8.1"很可能包含了JUnit库的JAR文件和其他相关资源,如文档、示例代码或许可证文件。开发者可以将这个JAR添加到他们的项目类路径中,以便使用JUnit进行单元测试。在实际操作中,这通常通过构建工具...

    Eclipse安装插件——junit

    而`junit3.8.2`和`junit`可能是Junit的不同版本,`junit3.8.2`表示的是Junit 3.8.2版本,这是一个较旧但仍然广泛使用的版本,而`junit`可能指的是Junit的某个较新版本。如果你在Eclipse中直接导入这些文件,可能需要...

    JUnit学习笔记

    这篇博客“JUnit学习笔记”可能是博主GreatJone在深入学习JUnit过程中所做的记录和总结,包括了JUnit的基本概念、核心组件、使用方法以及一些高级特性。 首先,JUnit的核心理念是基于断言的测试,即编写特定的测试...

    Junit学习笔记

    本学习笔记将深入探讨JUnit的核心概念、使用方法以及其在实际开发中的应用。 一、JUnit简介 JUnit是开源项目,由Ernst Konig和Kent Beck发起,最初是针对Java平台设计的。现在,JUnit已经成为Java开发者进行单元...

    junit4.8.1测试例子

    JUnit是Java编程语言中最常用的单元测试框架之一,用于编写和执行可重复的自动化测试用例。版本4.8.1是JUnit的一个稳定版本,包含了丰富的功能...通过分析和学习这个例子,我们可以更好地理解和应用JUnit进行单元测试。

Global site tag (gtag.js) - Google Analytics