zoukankan      html  css  js  c++  java
  • 单元测试JUnit 4

    介绍

     
    JUnit 4.x 是利用了 Java 5 的特性(Annotation)的优势,使得测试比起 3.x 版本更加的方便简单,JUnit 4.x 不是旧版本的简单升级,它是一个全新的框架,整个框架的包结构已经彻底改变,但 4.x 版本仍然能够很好的兼容旧版本的测试用例。
     
     

    使用

     
    先来点实在的,看看代码中是怎么使用的。其余的待会再说。
     

    下载

    加入项目

    • 把 junit4.8.1.jar 文件,加入到项目的 classpath 中。
     

    对比

     
    在代码之前,先让我们看一下 JUnit 4 和 JUnit 3 的区别,看看 JUnit 4 到底简化了哪些东西。
     
     
     

    演示代码

     1 import static org.junit.Assert.*;  
     2   
     3 import org.junit.Ignore;  
     4 import org.junit.Test;  
     5   
     6   
     7 public class TestWordDealUtil {  
     8     // 测试 wordFormat4DB 正常运行的情况  
     9     @Test  
    10     public void testWordFarmat4DBNormal() {  
    11         String target = "employeeInfo";  
    12         String result = WordDealUtil.wordFormat4DB(target);  
    13           
    14         assertEquals("employee_info", result);  
    15     }  
    16       
    17     // 测试 null 时的处理情况  
    18     @Test(expected=NullPointerException.class)  
    19     public void testWordFormat4DBNull() {  
    20         String target = null;  
    21         String result = WordDealUtil.wordFormat4DB(target);  
    22           
    23         assertNull(result);  
    24     }  
    25       
    26     // 测试空字符串的处理情况  
    27     @Test  
    28     public void testWordFormat4DBEmpty() {  
    29         String target = "";  
    30         String result = WordDealUtil.wordFormat4DB(target);  
    31           
    32         assertEquals("", result);  
    33     }  
    34       
    35     // 测试当首字母大写时的情况  
    36     //@Ignore  
    37     @Test  
    38     public void testWordFormat4DBBegin() {  
    39         String target = "EmployeeInfo";  
    40         String result = WordDealUtil.wordFormat4DB(target);  
    41           
    42         assertEquals("_employee_info", result);  
    43     }  
    44       
    45     // 测试当尾字母大写时的情况  
    46     @Test  
    47     public void testWordFormat4DBEnd() {  
    48         String target = "employeeInfoA";  
    49         String result = WordDealUtil.wordFormat4DB(target);  
    50           
    51         assertEquals("employee_info_a", result);  
    52     }  
    53       
    54     // 测试多个相连字母字母大写时的情况  
    55     @Test  
    56     public void testWordFormat4DBTogether() {  
    57         String target = "employeeAInfo";  
    58         String result = WordDealUtil.wordFormat4DB(target);  
    59           
    60         assertEquals("employee_a_info", result);  
    61     }  
    62 }  
    从图中可以看出,TestWordDealUtil 测试类中,有6个测试方法,其中有5个测试方法都已经通过,另外一个抛出了 NullPointerException (空指针)异常,需要注意的是,这里并不是单元测试的失败(Failure),而是测试出现了错误(Error)。那么,这两种有什么区别呢?下面就讨论一下这两者的区别。
     
    JUnit 将测试失败的情况分为两种:Failure 和 Error 。 Failure 一般是由单元测试使用的断言方法判断失败引起的,它表示在测试点发现了问题(程序中的 bug);而 Error 则是有代码异常引起的,这是测试目的之外的发现,它可能产生于测试代码本身的错误(也就是说,编写的测试代码有问题),也可能是被测试代码中的一个隐藏 bug 。不过,一般情况下是第一种情况。
     
     

    深入

     

    常用注解

    • @Before
    初始化方法,在任何一个测试方法执行之前,必须执行的代码。对比 JUnit 3 ,和 setUp()方法具有相同的功能。在该注解的方法中,可以进行一些准备工作,比如初始化对象,打开网络连接等。
     
    • @After
    释放资源,在任何一个测试方法执行之后,需要进行的收尾工作。对比 JUnit 3 ,和 tearDown()方法具有相同的功能。
     
    • @Test
    测试方法,表明这是一个测试方法。在 JUnit 中将会自动被执行。对与方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为 void ,而且不能有任何参数。如果违反这些规定,会在运行时抛出一个异常。不过,为了培养一个好的编程习惯,我们一般在测试的方法名上加 test ,比如:testAdd()。
     
    同时,该 Annotation(@Test) 还可以测试期望异常和超时时间,如 @Test(timeout=100),我们给测试函数设定一个执行时间,超过这个时间(100毫秒),他们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些 bug 了。而且,它还可以测试期望的异常,例如,我们刚刚的那个空指针异常就可以这样:@Test(expected=NullPointerException.class)。再来看一下测试结果。
     
     
    • @Ignore
    忽略的测试方法,标注的含义就是“某些方法尚未完成,咱不参与此次测试”;这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应的函数,只需要把 @Ignore 注解删除即可,就可以进行正常测试了。当然,这个 @Ignore 注解对于像我这样有“强迫症”的人还是大有意义的。每当看到红色条(测试失败)的时候就会全身不舒服,感觉无法忍受(除非要测试的目的就是让它失败)。当然,对代码也是一样,无法忍受那些杂乱不堪的代码。所以,建议大家都写漂亮的代码。这样人人都喜欢看你的代码。哎,有强迫症的人伤不起啊!
     
    • @BeforeClass
    针对所有测试,也就是整个测试类中,在所有测试方法执行前,都会先执行由它注解的方法,而且只执行一次。当然,需要注意的是,修饰符必须是 public static void xxxx ;此 Annotation 是 JUnit 4 新增的功能。
     
    • @AfterClass
    针对所有测试,也就是整个测试类中,在所有测试方法都执行完之后,才会执行由它注解的方法,而且只执行一次。当然,需要注意的是,修饰符也必须是 public static void xxxx ;此 Annotation 也是 JUnit 4 新增的功能,与 @BeforeClass 是一对。
     
     

    执行顺序

     
    所以,在 JUnit 4 中,单元测试用例的执行顺序为:
     


    每一个测试方法的调用顺序为:

     
     

    规范

     
    最后,在来说说关于测试的规范,这些规范是从编程规则,以及日常的实践中,由那些大牛们总结出来的。作为后人的我们,在大树下乘凉的同时,更要遵守这些规则,使得大树更加茁壮成长。
    • 单元测试代码应位于单独的 Source Folder 下
    此 Source Folder 通常为 test ,这样可以方便的管理业务代码与测试代码。其实,在项目管理工具 Maven 上已经做了这种规范了。在我们自己写代码时,注意一下即可。
     
     
    • 测试类应该与被测试类位于同一 package 下
    便于进行管理,同时减少引入带测试类的麻烦。
    • 选择有意义的测试方法名
    无论是 JUnit 4 ,还是 JUnit 3 ,单元测试方法名均需使用 test<待测试方法名称>[概要描述] ,如 public void testDivideDivisorIsZero() ,很容易知道测试方法的含义。
     
    • 保存测试的独立性
    每项单元测试都必须独立于其他所有单元测试而运行,因为单元测试需能以任何顺序运行。
     
    • 为暂时未实现的测试代码忽略(@Ignore)或抛出失败(fail)
    在 JUnit 4 中,可以在测试方法上使用注解 @Ignore 。在 JUnit 3 中,可以在未实现的测试方法中使用 fail("测试方法未实现"); 以告知失败是因为测试方法未实现。
     
    • 在调用断言(assert)方法时给出失败的原因
    在使用断言方法时,请使用带有 message 参数的 API ,并在调用时给出失败时的原因描述,如 assertNotNull("对象为空", new Object())。
     
     

    结束语

     
    请牢记:测试任何可能的错误。单元测试不是用来证明您是对的,而是为了证明您没有错。
     
    JUnit 4 到这里就差不多了,如果文章中有什么不对的地方,还希望各位大牛拍砖。说了这么多,能真正用上才是王道,当然,希望以我这篇文章为契机,IT 界的精英们,之前没有用单元测试的,能够唤醒你们体内的小宇宙;之前已经在用的,也能够再体会一番,提高开发的效率,写出 漂亮 的代码。
  • 相关阅读:
    HDU4474 Yet Another Multiple Problem BFS搜索
    HDU4473 Exam 数学分析
    2013ACM多校联合(4)
    POJ1273 网络流...
    HDU4472 Count 递推
    POJ1149 PIGS 网络流
    UVA10881 Piotr's Ants 想法题
    javascript js string.Format()收集
    修改 设置 vs.net 网站 调试 设为 起始页
    【转】HTML5杂谈 概念与现行游戏 割绳子 宝石迷阵
  • 原文地址:https://www.cnblogs.com/vianzhang/p/7649295.html
Copyright © 2011-2022 走看看