`
silent.wong
  • 浏览: 14736 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
最近访客 更多访客>>
社区版块
存档分类
最新评论

JUNIT4 简单入门

阅读更多

JUnit 4是JUnit框架有史以来的最大改进,其主要目标便是利用Java 5的Annotation特性简化测试用例的编写。让我们看看如何使用JUnit 4来进行Unit测试。

请注意:本文主要介绍JUnit 4的最新特性和用法,并不会讲解Unit测试的基础。如果你对JUnit框架还不熟悉,请先参考“Eclipse快速上手指南 (2) 使用JUnit测试”一文,学习如何编写JUnit测试。

我们使用的开发环境是Eclipse 3.2,它已经自带了JUnit 4.1,你需要将JUnit 4 Library添加到项目用到的Library中。另外,必须使用JDK 5.0或更高版本。

要在Eclipse环境之外运行JUnit,需要下载JUnit 4.1,具体请访问JUnit.org

我们先看一个简单的Math类:

 

package com.javaeedev.junit4;
public class Math {

    
public int abs(int value) {
        
return value>=0 ? value : (-value);
    }

    
public int div(int a, int b) {
        
return a / b;
    }

    
/**
     * BUG: if b less than 0!
     
*/
    
public float exp(int a, int b) {
        
float r = 1;
        
for(int i=0; i<b; i++)
            r 
= r * a;
        
return r;
    }
}

 

注意exp()方法是有Bug的,如果传入参数2, -1,则期待的返回值应为0.5F,但实际返回值为1.0F。

下面我们看看传统的JUnit的TestCase:

 

public class MathTest extends TestCase {

    
public void setUp() { super.setUp(); }
    
public void tearDown() { super.tearDown(); }

    
public void testAbs() { assertTrue(true); }
    
public void testDiv() {...}
    
public void testExp() {...}

}

 

JUnit依赖反射来执行每个以test开头的方法。然而,在最新的JUnit 4中,由于有了Annotation的支持,我们的测试方法不需要再以testXxx标识了,而是写上一个@Test标注即可。例如:

 

@Test public void doAbs() {...}

 

甚至MathTest类也不必继承自TestCase。你也许会想到,不继承自TestCase就无法调用assertXxx方法了,正因为如此,所有的assertXxx方法全部以静态方法被放入了Assert类,使用Assert.assertXxx()调用。如果使用

 

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即可。

来看看使用Annotation的MathTest:

 

package com.javaeedev.junit4;

import static org.junit.Assert.*;

import org.junit.*;

public class MathTest {

    
public MathTest() {
        System.out.println(
"new MathTest instance.");
    }

    @Before
    
public void setUp() throws Exception {
        System.out.println(
"call @Before before a test method");
    }

    @After
    
public void tearDown() throws Exception {
        System.out.println(
"call @After after a test method");
    }

    @Test
    
public void doAbs() {
        Math math 
= new Math();
        assertEquals(
200, math.abs(200));
        assertEquals(
100, math.abs(-100));
        assertEquals(
0, math.abs(0));
    }

    @Test
    
public void doDiv() {
        Math math 
= new Math();
        assertEquals(
5, math.div(10020));
        assertEquals(
4, math.div(10021));
    }

    @Test(expected
=ArithmeticException.class)
    
public void doDiv0() {
        
new Math().div(1270);
    }

    @Test(timeout
=1)
    
public void doLongTimeTask() {
        
double d = 0;
        
for(int i=1; i<10000000; i++)
            d
+=i;
    }

    @Test
    
public void testExp() {
        Math math 
= new Math();
        assertEquals(32f, math.exp(
25), 0.001f);
        assertEquals(1f, math.exp(
20), 0.001f);
        assertEquals(
0.5f, math.exp(2, (-1)), 0.001f);
    }

}

 

对测试异常,JUnit 4可以用expected=Exception.class来期待一个预期的异常,而不必编写

 

try {
  ...
  fail(
"No exception");
}
catch(Exception e) {
  
// OK!
}

 

来看看doDiv0测试,我们期待一个除数为0的ArithmeticException,因此编写如下测试方法:

 

@Test(expected=ArithmeticException.class)
public void doDiv0() {
    
new Math().div(1270);
}

 

对于非常耗时的测试,@Test还有一个timeout来标识该方法最长执行时间,超过此时间即表示该测试方法失败:

 

@Test(timeout=1)
public void doLongTimeTask() {
    
double d = 0;
    
for(int i=1; i<10000000; i++)
        d
+=i;
}

 

以上方法若执行时间超过1ms则测试失败,由于依赖CPU的执行速度,在不同的机器上测试结果也不同。

JUnit 4另一个较大的变化是引入了@BeforeClass和@AfterClass,它们在一个Test类的所有测试方法执行前后各执行一次。这是为了能在@BeforeClass中初始化一些昂贵的资源,例如数据库连接,然后执行所有的测试方法,最后在@AfterClass中释放资源。

正如你能想到的,由于@BeforeClass和@AfterClass仅执行一次,因此它们只能标记静态方法,在所有测试方法中共享的资源也必须是静态引用:

 

private static Object dbConnection;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
    System.out.println(
"call @BeforeClass and init database connection");
    dbConnection 
= new Object();
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
    System.out.println(
"call @AfterClass to release database connection");
    dbConnection 
= null;
}

 

最后执行测试用例,可以看到结果:

各个方法执行顺序如下:

call @BeforeClass and init database connection

new MathTest instance.
call @Before before a test method
call @After after a test method

new MathTest instance.
call @Before before a test method
call @After after a test method

...

call @AfterClass to release database connection

可以看到,@BeforeClass是在实例化MathTest之前调用的,因此不能在构造方法中初始化共享资源。

最后需要注意的是由于Java 5的自动Box/Unbox特性,在调用assertEquals()时要特别注意,如果你传入:

assertEquals(100F, 100);

则按照自动Box变为:

assertEquals(new Float(100F), new Integer(100));

测试失败,因为Float类和Integer类不是同一类型。

因此要特别注意float和double的测试。事实上对float和double应使用

assertEquals(float, float, float delta);
assertEquals(double, double, double delta);

delta指定了两个作比较的浮点数的相差范围,在此范围内的两个浮点数将认为相等。可以传入一个很小的数例如0.0001F。 

JUnit 4非常适合使用Java 5的开发人员,但是无法在Java 1.4中获得这些好处,并且,也不与以前的版本兼容。因此,如果你正在使用Java 5,就可以考虑使用JUnit 4来编写测试。

分享到:
评论

相关推荐

    Junit4单元测试入门例子

    总结,Junit4使得Java的单元测试变得简单而直观。通过注解,我们可以快速定义测试方法,结合断言库进行结果验证,确保代码质量。在本例中,我们学会了如何为Calculate类的加减乘除方法编写有效的单元测试,为后续的...

    JUnit入门及简单使用

    以下是一个简单的JUnit4测试示例,针对上述`A`类的`sum()`和`reverse()`方法进行测试: ```java import org.junit.Test; import static org.junit.Assert.assertEquals; public class ATest { @Test public void...

    junit5学习入门

    ### JUnit5学习入门知识点详解 #### 一、JUnit简介 JUnit是一个开源的Java单元测试框架,被广泛应用于软件开发中的测试驱动开发(TDD)流程之中。它支持开发者通过编写测试代码来验证软件功能是否符合预期,从而提高...

    Junit4单元测试必备入门教程

    JUnit4单元测试必备入门教程 JUnit4概述 -------- JUnit4是JUnit框架有史以来最大的改进,其主要目标是利用Java5的Annotation特性简化测试用例的编写。Annotation是一种元数据,用于描述数据。在Java中可以用来和...

    JUnit API和入门手册 chm

    本资源包含“JUnit API和入门手册”以及“JUnit In Action”电子书,将帮助你深入理解和掌握JUnit的核心概念和使用方法。 首先,`JUnit4.1.chm`文件是JUnit 4.1版本的API参考文档,通常包含了类、接口、方法等详细...

    junit4 单元测试源码

    “入门级学习材料”表明这个压缩包可能是为初学者准备的,涵盖了如何使用JUnit4框架创建和运行测试的基本步骤。Eclipse开发环境是一个流行的Java集成开发环境,它支持JUnit插件,使得在Eclipse中编写和运行JUnit测试...

    junit 入门培训ppt

    本文将深入探讨JUnit入门培训的关键概念和技术。 首先,我们要理解什么是Test Driven Development(TDD),即测试驱动开发。TDD是一种软件开发方法论,它提倡在编写实际业务代码之前先编写测试。通过这种方式,...

    Junit实例图解,Junit快速入门

    下面是一个简单的Junit4测试案例,涉及了对`WordDealUtil`类中`wordFormat4DB`方法的测试: ```java package com.ai92.cooljunit; import static org.junit.Assert.assertEquals; import org.junit.Test; public ...

    jUnit测试框架入门详解(加强版)

    jUnit 测试框架入门详解 jUnit 是一个开源的 Java 语言的单元测试框架,其专门针对 Java 语言设计,使用十分广泛。jUnit 已成事实上的标准单元测试框架(行业标准)。 jUnit 的优点包括:可以使用断言...

    Junit4学习笔记—入门篇.pdf

    ### JUnit4学习笔记——入门篇 #### 一、配置MyEclipse在项目中引入JUnit4.jar包 在使用JUnit4进行单元测试之前,首先需要确保开发环境已正确配置JUnit库。对于使用MyEclipse IDE的开发者来说,可以通过以下步骤...

    Junit入门实验Junit入门实验

    这个"Junit入门实验"旨在帮助初学者理解和掌握JUnit的基本概念和使用方法。通过这个实验,你将学习如何设置测试环境,创建测试类,编写测试用例,并理解断言和异常处理。 1. **安装与引入JUnit** 在开始之前,你...

    JUnit入门

    ### JUnit入门详解 #### 一、JUnit简介 JUnit是一个流行的Java单元测试框架,它提供了一种简单有效的方式来编写和运行测试用例。对于初学者来说,了解JUnit的基本概念和使用方法是非常重要的。 #### 二、JUnit的...

    dom4j_xpath_junitTest.zip

    《深入理解DOM4J、XPath与JUnit:快速入门与实战测试》 DOM4J、XPath和JUnit是Java开发中不可或缺的三个重要工具。DOM4J是处理XML文档的一个强大库,XPath则是XML路径语言,用于在XML文档中查找信息,而JUnit则是...

    JUnit学习笔记之NetBeans入门篇

    在弹出的对话框中,为新库命名(例如“JUnit4”),点击“下一步”,接着选择“添加JAR/Folder”,找到JUnit的jar文件(通常在JUnit的安装目录下),添加并完成库的创建。确保在你的项目中引用了这个库,这样你就能...

    Junit 入门与提高实例代码

    《Junit 入门与提高实例代码》是针对Java开发者,特别是J2EE环境下的测试工程师的一份宝贵资源。这份资料旨在帮助初学者快速掌握Junit的使用,并通过实例提升测试技能,确保J2EE应用的质量和稳定性。下面将详细阐述...

    JUnit测试代码示例

    JUnit3是许多开发者入门测试的起点,虽然现在更多的项目转向了新版本,但理解JUnit3的基础仍然很有价值。 JUnit3的主要特点包括: 1. **测试注解**:在JUnit3中,测试类和方法是通过继承`junit.framework.TestCase...

Global site tag (gtag.js) - Google Analytics