您的位置:首页 > 其它

JUnit4学习指导书

2010-12-11 21:37 155 查看
在我以前的实际的工作中,很多项目都没有写单元测试用例。写单元测试用例常常是程序员十分厌倦的一个项目活动,很多人觉得没有必要、浪费时间。所有这些都是因为没有认识到测试的重要性:

测试能够使我们尽量早的发现程序的bug,一个bug被隐藏的时间越长,修复这个bug的代价就越大。在《快速软件开发》一书中已引用了大量的研究数据指出:最后才修改一个bug的代价是在bug产生时修改它的代价的10倍。在现代软件开发过程中,不管是xp还是rup 都是十分重视单元测试,已经把单元测试作为贯穿整个开发周期的一项重要的开发活动。单元测试如此重要,那么怎样写好单元测试用例呢?这就需要了解 Junit及其相关的测试工具了。

Junit简介:

Junit最初是由Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),为单元测试(Unit Test)的支持框架。用来编写和执行重覆性的测试。即所谓白盒测试。

它包括了以下的特性:

对预期结果作断言

提供测试装备的生成与销毁

易于组织执行测试

图形与文字界面的测试器

Junit的环境配置

环境:Eclipse

2.1 创建java Project : 项目名称:“Junit4”

2.2 添加Junit4 libraires

选择项目Junit4(在Package Explorer中) -> 右击鼠标 -> 选择properties -> 选择Java Build Path (在左边的菜单中) -> 在右边选择标签 Libraries (如图1) -> 单击按钮“Add Library” (如图二) -> 选择JUnit , 单击按钮 “Next>” (如图三) -> 选择JUnit library version 为: JUnit4 -> 单击按钮“Finish” –> 单击按钮 “OK”





(图一)





下面我们以一个简单的例子来介绍如何使用 Junit4同Junit3编写测试用例:

public Class XXXX{

public String hello(){

return “hello”;

}

}

对于这个类的用junit3编写测试用例:

import junit.framework.TestCase;

public Class XXXXTest extends TestCase{

public void testHello(){

asssertEqual(new XXXX().Hello(),”hello”);

}

}

用junit4编写测试用例:

import static org.junit.framework.assertEqual;

import org.junit.Test;

public Class XXXXTest{

@Test

public void helloTest(){

asssertEqual(new XXXX().Hello(),”hello”);

}

}

从上面例子我们对Junit3和Junit4有了一个初步的印象,下面我们重点介绍Junit4与Junit3的主要区别。

JUnit3JUnit4
必须引入类TestCase
import junit.framework.TestCase;
必须引入
import org.junit.Test;
import static org.junit.Assert.*;
必须继承类TestCase
class BaseClassTest extends TestCase
不需要
测试方法必须以test开头
public void testMethod ()
不需要,
但是类开始的时候要标记 @Test
通过assert*方法来判断结果
assertTrue(baseClass.method ().equals(“test.junit.BaseClass”));
3.1 Junit4引入了java 5.0的注释技术:

这两个版本最大的区别在JUnit3.x中测试必须继承 TestCase,并且每个方法名必须以test开头。比如:testMethod1()而在JUnit4.x中不必继承TestCase,采用了注解的方式。只要在测试的方法上加上注解@Test即可,从而不必再遵循以前的一些显式约定和反射定位测试;在JUnit4.x中如果继承了TestCase,注解就不起作用了。并且有很重要的一点就是在JUnit4.x中继承了TestCase后,在OutLine视图中测试单个方法时,结果整个类都run 了。还有一点就是,在3.x中需要实现setUp和tearDown方法,而在4.x中无需这样,可以自定义需要在测试前和测试后的方法,在方法前加上 @before,@after就可以了。所以在JUnit4.x不必继承TestCase用注解即可对单个方法进行测试。

3.2 JUnit4引入了一个JUnit3中没有的新特性——类范围的 setUp() 和tearDown() 方法。任何用 @BeforeClass 注释的方法都将在该类中的测试方法运行之前刚好运行一次,而任何用 @AfterClass 注释的方法都将在该类中的所有测试都运行之后刚好运行一次。

3.3 异常测试:

异常测试是Junit4中的最大改进。Junit3的异常测试是在抛出异常的代码中放入try块,然后在try块的末尾加入一个fail()语句。

例如该方法测试一个被零除抛出一个ArithmeticException:

该方法不仅难看,而且试图挑战代码覆盖工具,因为不管测试是否通过还是失败,总有一些代码不被执行。在JUni4中,可以编写抛出异常的代码,并使用注释来声明该异常是预期的:

如果没有异常抛出或者抛出一个不同的异常,那么测试就将失败。

3.4 JUnit4添加了两个比较数组的assert() 方法:

public static void assertEquals(Object[] expected, Object[] actual)

public static void assertEquals(String message, Object[] expected, Object[] actual)

这两个方法以最直接的方式比较数组:如果数组长度相同,且每个对应的元素相同,则两个数组相等,否则不相等。数组为空的情况也作了考虑。

assertEquals()方法用来断定您希望的预期结果与单元方法实际的传回结果是否相同,如果不同则发出断言

JUnit 4 常用的几个annotation 介绍

★ @Before:初始化方法,在任何一个测试执行之前必须执行的代码;

★ @After:释放资源,在任何测试执行之后需要进行的收尾工作。在每个测试方法执行之后执行一次,该annotation只能修饰public void 方法;

★ @Test:测试方法,表明这是一个测试方法。在Junit中将会自动被执行。该annotation只你呢个修饰public void 方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。如果违反这些规定,会在运行时抛出一个异常。至于方法内该写些什么,那就要看你需要测试些什么了;在这里可以测试期望异常和超时时间,如 @Test(timeout = 100),我们给测试函数设定一个执行时间,超过了这个时间(100毫秒),它们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些Bug了。

★ @Ignore:忽略的测试方法,标注的含义就是“某些方法尚未完成,暂不参与此次测试”;这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore标注删去,就可以进行正常的测试。

★ @BeforeClass:针对所有测试,只执行一次,且必须为public static void;

★ @AfterClass:针对所有测试,将会在所有测试方法执行结束后执行一次,且必须为public static void;

所以一个Junit 4 的单元测试用例执行顺序为:@BeforeClass –> @Before –> @Test –> @After –> @AfterClass;每一个测试方法的调用顺序为:@Before –> @Test –> @After。

如下面例子:

import static org.junit.Assert.*; import org.junit.After;import org.junit.AfterClass;import org.junit.Before;import org.junit.BeforeClass;import

org.junit.Ignore;import org.junit.Test; public class JUnit4Test {

@Before

public void before() {

System.out.println(“@Before”);

}

@Test

public void test() {

System.out.println(“@Test”);

assertEquals(5 + 5, 10);

}

@Ignore

@Test

public void testIgnore() {

System.out.println(“@Ignore”);

}

@Test(timeout = 50)

public void testTimeout() {

System.out.println(“@Test(timeout = 50)”);

assertEquals(5 + 5, 10);

}

@Test(expected = ArithmeticException.class)

public void testExpected() {

System.out.println(“@Test(expected = Exception.class)”);

throw new ArithmeticException();

}

@After

public void after() {

System.out.println(“@After”);

}

@BeforeClass

public static void beforeClass() {

System.out.println(“@BeforeClass”);

};

@AfterClass

public static void afterClass() {

System.out.println(“@AfterClass”);

};

};

右击测试类,选择Junit运行……

输出结果如下:

@BeforeClass

@Before

@Test(timeout = 50)

@After

@Before

@Test(expected = Exception.class)

@After

@Before

@Test

@After

@AfterClass

在eclipse中junit运行结果视图中可以看到testIgnore是被忽略的,没有执行;还有其中有一个方法运行报错。

常用的断言介绍

4.1 、assertEquals([String message],Object target,Object result)

target与result不相等,中断测试方法,输出message

assertNull 断言对象为null,若不满足,方法抛出带有相应信息的AssertionFailedError异常。

assertEquals(a, b) 测试a是否等于b(a和b是原始类型数值(primitive value)或者必须为实现比较而具有equal方法)

assertEquals

断言两个对象相等,若不满足,方法抛出带有相应信息的AssertionFailedError异常。

例如计算器加法功能的测试可以使用一下验证:

Assert.assertEquals(0,result);

4.2 、assertTrue/False([String message],Boolean result)

Result为 false/true,中断测试方法,输出message

assertTrue

断言条件为真,若不满足,方法抛出带有相应信息的AssertionFailedError异常。

assertFalse(a) 测试a是否为false(假),a是一个Boolean数值。

assertFalse

断言条件为假,若不满足,方法抛出带有相应信息的AssertionFailedError异常。

4.3 、assertNotNull/Null([String message],Obejct result

Retult= = null/result!=null,中断测试方法,输出message

assertNotNull(a) 测试a是否非空,a是一个对象或者null。

assertNotNull 断言对象不为null,若不满足,方法抛出带有相应信息的AssertionFailedError异常。

4.4 、assertSame/NotSame(Object target,Object result)

Traget与result 不指向/指向 同一内存地址(实例),中断测试方法,输出message

assertNotSame(a, b) 测试a和b是否没有都引用同一个对象。

assertNotSame

断言两个引用指向不同对象,若不满足,方法抛出带有相应信息的AssertionFailedError异常。

assertSame 断言两个引用指向同一个对象,若不满足,方法抛出带有相应信息AssertionFailedError异常。

4.5 、fail([String message])

中断测试方法,输出message

Fail 让测试失败,并给出指定信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: