太久没有用junit写测试了,前几天被一个面试官问的自己很傻,所以特意在此重新学习和总结一下
使用junit做测试目的是尽量早的发现程序的bug,一个bug隐藏的时间越久,修复他的代价就越大。
Junit简介:
Junit最初是由Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),为单元测试(Unit Test)的支持框架。用来编写和执行重覆性的测试。即所谓白盒测试。
它包括了以下的特性:
1 对预期结果作断言
2 提供测试装备的生成与销毁
3 易于组织执行测试
4 图形与文字界面的测试器
Junit的环境配置
环境:Eclipse 中配置junit,选择项目Junit4(在Package Explorer中) -> 右击鼠标 -> 选择properties -> 选择Java Build Path (在左边的菜单中) -> 在右边选择标签 Libraries -> 单击按钮“Add Library” -> 选择JUnit , 单击按钮 “Next>” -> 选择JUnit library version 为: JUnit4 -> 单击按钮“Finish” –> 单击按钮 “OK”
Junit4是Junit框架有史以来的最大改进,其主要目标是利用java5的Annotation特性来简化测试用例的编写。Junit4的官方网址是http://www.junit.org/。
总结一下3-4的不同,及4的改进
下面我们以一个简单的例子来介绍如何使用 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;
//这两个是junit4中必须导入的s
public Class XXXXTest{
@Test
public void helloTest(){
asssertEqual(new XXXX().Hello(),”hello”);
}
}
从上面例子我们对Junit3和Junit4有了一个初步的印象,下面我们重点介绍Junit4与Junit3的主要区别。
JUnit3 JUnit4
必须引入类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 常用的断言介绍
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 让测试失败,并给出指定信息。
Java代码
@Test
public void add(){
assertEquals("不相等","1","1");
}
@Test
public void add(){
assertEquals("不相等","1","1");
}
Junit4中测试类不需要继承自TestCase。不继承TestCase就无法调用assertXXX方法了,正因为如此,所有的assertXXX方法全部以静态方法被放入了Assert类,使用Assert.assertXXX()调用。使用方法是
Java代码
import static org.junit.Assert.*;
import static org.junit.Assert.*;
setUp()和tearDown()方法也依赖@Before和@After标记,这样做的最大的好处是在继承体系内不必担心忘记了在setUp()方法中调用父类的super.setUp()方法,JUnit框架会自动处理父类的@Before和@After标记的方法。
并且,JUnit框架对@Before和@After的调用顺序类似于类的构造方法和析构方法,即@Before按照父类到子类的顺序调用,@After则相反,这样保证了资源的正确获取和释放。
当然,不再强迫必须使用setUp和tearDown作为方法名,可以使用更有意义的方法名,例如:initDatabase()和closeDatabase(),只要它们被标注了@Before和@After即可。
Java代码
@Before
public void test1(){
System.out.println("开始初始化----");
}
@After
public void test2(){
System.out.println("销毁资源----");
}
@Before
public void test1(){
System.out.println("开始初始化----");
}
@After
public void test2(){
System.out.println("销毁资源----");
}
JUnit 4另一个较大的变化是引入了@BeforeClass和@AfterClass,它们在一个Test类的所有测试方法执行前后各执行一次。这是为了能在@BeforeClass中初始化一些昂贵的资源,例如数据库连接,然后执行所有的测试方法,最后在@AfterClass中释放资源。
正如你能想到的,由于@BeforeClass和@AfterClass仅执行一次,因此它们只能标记静态方法,在所有测试方法中 共享的资源也必须是静态引用:
Java代码
@BeforeClass
public static void test11(){
System.out.println("所有方法调用前要做的事情");
}
@AfterClass
public static void test22(){
System.out.println("所有方法测试完后要调用的");
}
@BeforeClass
public static void test11(){
System.out.println("所有方法调用前要做的事情");
}
@AfterClass
public static void test22(){
System.out.println("所有方法测试完后要调用的");
}
Junit4可以使用expected=Exception.class来期待一个预期的异常,而不必编写
try{
fail("No exception")
}catch(Exception e){
//Ok
}
例如:测试数组长度越界的异常。
Java代码
@Test(expected= IndexOutOfBoundsException.class)
public void empty() {
System.out.println("IndexOutOfBoundsException");
new ArrayList<Object>().get(0);
}
@Test(expected= IndexOutOfBoundsException.class)
public void empty() {
System.out.println("IndexOutOfBoundsException");
new ArrayList<Object>().get(0);
}
对于非常耗时的测试,@Test还有一个timeout来标识该方法最长执行时间,超过此时间即表示该测试方法失败:
Java代码
@Test(timeout=1)
public void infinity() {
while(true);
}
@Test(timeout=1)
public void infinity() {
while(true);
}
以上方法若执行时间超过1ms则测试失败,由于依赖CPU的执行速度,在不同的机器上测试结果也不同。
运行多个测试用例:
Java代码
JUnitCore.runClasses(MyTest.class);
runClasses方法的参数可以写多个测试类的class
下面是一个简单的测试用例。
Java代码
import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class MyTest {
@Before
public void test1(){
System.out.println("开始初始化----");
}
@BeforeClass
public static void test11(){
System.out.println("所有方法调用前要做的事情");
}
@Test
public void add(){
assertEquals("不相等","1","1");
}
@Test
public void add2(){
System.out.println("测试用例2");
assertEquals("不相等","1","1");
}
@Test(expected= IndexOutOfBoundsException.class)
public void empty() {
System.out.println("IndexOutOfBoundsException");
new ArrayList<Object>().get(0);
}
@Test(timeout=1)
public void infinity() {
while(true);
}
@After
public void test2(){
System.out.println("销毁资源----");
}
@AfterClass
public static void test22(){
System.out.println("所有方法测试完后要调用的");
}
}
import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class MyTest {
@Before
public void test1(){
System.out.println("开始初始化----");
}
@BeforeClass
public static void test11(){
System.out.println("所有方法调用前要做的事情");
}
@Test
public void add(){
assertEquals("不相等","1","1");
}
@Test
public void add2(){
System.out.println("测试用例2");
assertEquals("不相等","1","1");
}
@Test(expected= IndexOutOfBoundsException.class)
public void empty() {
System.out.println("IndexOutOfBoundsException");
new ArrayList<Object>().get(0);
}
@Test(timeout=1)
public void infinity() {
while(true);
}
@After
public void test2(){
System.out.println("销毁资源----");
}
@AfterClass
public static void test22(){
System.out.println("所有方法测试完后要调用的");
}
}
运行测试用例:
Java代码
import junit.framework.JUnit4TestAdapter;
import org.junit.runner.JUnitCore;
public class MyTest3 {
public static void main(String[] args) {
JUnitCore.runClasses(MyTest.class);
System.out.println();
//MyTest3.suite();
}
public static junit.framework.Test suite() {
return new JUnit4TestAdapter(MyTest.class);
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
相关推荐
@Test:这是 JUnit4 中的核心元数据,用于标记测试方法。当 JUnit4 运行测试时,会查找所有带有 @Test 注解的方法,并逐一执行。@BeforeClass 和 @AfterClass:这两个元数据分别表示在整个测试类运行前只执行一次的...
### JUnit4学习笔记——入门篇 #### 一、配置MyEclipse在项目中引入JUnit4.jar包 在使用JUnit4进行单元测试之前,首先需要确保开发环境已正确配置JUnit库。对于使用MyEclipse IDE的开发者来说,可以通过以下步骤...
Junit学习笔记,希望有用~~~~~~~~~~~~~~~~~~~~~~
这篇博客“JUnit学习笔记”可能是博主GreatJone在深入学习JUnit过程中所做的记录和总结,包括了JUnit的基本概念、核心组件、使用方法以及一些高级特性。 首先,JUnit的核心理念是基于断言的测试,即编写特定的测试...
《Junit 4.0 学习笔记》 JUnit 是一个广泛使用的Java编程语言的单元测试框架,尤其在敏捷开发和持续集成环境中扮演着至关重要的角色。本文将深入探讨JUnit 4.0版本的主要特性、核心概念以及如何有效利用它进行单元...
现在的版本都4.3.1,3.8.1的感觉好象不好找,虽然www.junit.org能够找到,但对我们这种英语不好的来说,还是不好找,再说了,现在好多的教程都是以3.8.1来写的,所以在这里把我找到的3.8.1传上来供大家以后下载 博文链接:...
通过这份Junit学习笔记,你可以掌握单元测试的基本思想,熟练运用JUnit进行代码质量的保障。在实际开发中,单元测试不仅能帮助找出错误,还能在重构时提供安全保障,提高代码质量。不断学习和实践,你会发现自己在...
"Junit良葛格学习笔记"很可能包含了一系列关于如何有效利用JUnit进行测试的教程和示例。下面将详细阐述JUnit的核心概念、功能以及在实际开发中的应用。 1. **JUnit简介**: JUnit是由Ernst Leiss和Kent Beck开发的...
这个“Junit学习.rar”压缩包显然包含了关于JUnit从3.8到4.9版本的学习资料,包括可能的操作手册、教程文档以及个人的学习笔记。以下是基于这些资源可能涵盖的一些关键知识点: 1. **JUnit基础知识**:了解JUnit的...
关于"浪曦JUNIT4笔记"可能涉及的内容,浪曦可能对JUnit4的使用提供了详细的教程或者最佳实践,包括但不限于如何组织测试类,如何使用Mockito进行模拟对象测试,以及如何利用TestNG或Spock等其他测试框架与JUnit4结合...
本篇笔记将带你进入JUnit与NetBeans的结合使用世界,让你在NetBeans中更高效地进行单元测试。 首先,我们需要安装JUnit库到NetBeans。在NetBeans中,打开“工具”菜单,选择“库”,然后点击“新建库”。在弹出的...
总之,这个学习资源将带你深入理解JUnit的基本概念和高级特性,通过阅读`JUnit学习笔记.txt`并动手实践其中的示例,你将能熟练掌握如何利用JUnit3和JUnit4进行有效的单元测试,从而提升代码质量和项目稳定性。
JUnit知识点滴集合笔记,这个包里面包括了好几篇文档,一定会让你对JUNIT有一个全新的认识。 JUnit 4 抢先看.doc JUnit in java 真正的测试用例实战.doc JUnit起步.doc junit实现过程.doc JUnit中如何测试异常.doc ...
第4章:讲述不同类型的软件测试以及他们在应用生命周期中扮演的角色,并讲述如何为可测试性设计。如 何实施测试先行的开发。 第5章:探讨了将Junit整合进开发环境的各种方式。并提及了用Ant,maven和Eclipse来自动化...
林信良学习笔记(内容):ajax学习笔记,算法学习笔记,计算机图形学,C++学习笔记,设计模式,Hibernate学习笔记,Java学习笔记,JSF,JSP/Servlet,JUnit,Spring,Struts等
在“北京圣思园 junit 全套笔记及源码”中,你将深入学习 JUnit 的各种功能和最佳实践。以下是一些关键知识点: 1. **安装与配置**:首先,你需要了解如何在你的开发环境中安装 JUnit,通常是通过 Maven 或 Gradle ...
在“JUnit4入门学习笔记.doc”这份文档中,我们可以期待找到以下关键知识点: 1. **JUnit介绍**:首先会介绍JUnit的基本概念,包括它的起源、目标以及在软件开发中的地位,以及与其它测试框架的比较。 2. **环境...