发布新日志

  • JUnit4单元测试实例图解

    2010-01-06 16:51:05

    1.软件环境

    Eclipse

    JUnit4

     

    2.为项目添加JUnit4

    A.添加Eclipse自带的Junit4

    打开项目属性页->选择Java Build Path->点击Add Library->在弹出的对话框中选择JUnit->选择JUnit版本后点击Finish.(2.1)

    2.1

    B添加Junit其他方法

    打开项目属性页->选择Java Build Path->点击Add External JARS->选择JUnit地址后点击确定.(2.2)

    2.2

    3. 修改代码目录

    分别为单元测试代码与被测试代码创建单独的目录,单元测试代码和被测试代码使用一样的包,不同的目录。

    选择项目属性->选择Java Build Path->在根目录下添加一个新目录,并把它加入到项目源代码目录中.(3.1)

    3.1

     

    4.JUnit元数据

    @Before
    使用了该元数据的方法在每个测试方法执行之前都要执行一次。
    @After

    使用了该元数据的方法在每个测试方法执行之后要执行一次。
    注意:@Before@After标示的方法只能各有一个。这个相当于取代了JUnit以前版本中的setUptearDown方法,当然你还可以继续叫这个名字,不过JUnit不会霸道的要求你这么做了。
    @Test(expected=*.class)
    JUnit4.0之前,对错误的测试,我们只能通过fail来产生一个错误,并在try块里面assertTruetrue)来测试。现在,通过@Test元数据中的expected属性。expected属性的值是一个异常的类型
    @Test(timeout=xxx):
    该元数据传入了一个时间(毫秒)给测试方法,
    如果测试方法在制定的时间之内没有运行完,则测试也失败。
    @ignore

    元数据标记的测试方法在测试中会被忽略。当测试的方法还没有实现,或者测试的方法已经过时,或者在某种条件下才能测试该方法(比如需要一个数据库联接,而 在本地测试的时候,数据库并没有连接),那么使用该标签来标示这个方法。同时,你可以为该标签传递一个String的参数,来表明为什么会忽略这个测试方 法。比如:@lgnore(“该方法还没有实现”),在执行的时候,仅会报告该方法没有实现,而不会运行测试方法。

    5.实例

    被测试代码:

    package com.ai92.cooljunit;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    /**
    * 对名称、地址等字符串格式的内容进行格式检查
    * 或者格式化的工具类
    *
    * @author Ai92
    */
    public class WordDealUtil {
      /**
       * Java对象名称(每个单词的头字母大写)按照
       * 数据库命名的习惯进行格式化
       * 格式化后的数据为小写字母,并且使用下划线分割命名单词
       *
       * 例如:employeeInfo 经过格式化之后变为 employee_info
       *
       * @param name  Java对象名称
       */
      public static String wordFormat4DB(String name){
        Pattern p = Pattern.compile("[A-Z]");
        Matcher m = p.matcher(name);
        StringBuffer sb = new StringBuffer();
        
        while(m.find()){
          m.appendReplacement(sb, "_"+m.group());
        }
        return m.appendTail(sb).toString().toLowerCase();
      }
    }

     

    单元测试代码:

    package com.ai92.cooljunit;
    import static org.junit.Assert.assertEquals;
    import org.junit.Test;
    public class TestWordDealUtil {
      //测试wordFormat4DB正常运行的情况
      @Test public void wordFormat4DBNormal(){
        String target = "employeeInfo";
        String result = WordDealUtil.wordFormat4DB(target);
        
        assertEquals("employee_info", result);
      }

    //测试 null 时的处理情况
      @Test public void wordFormat4DBNull(){
        String target = null;
        String result = WordDealUtil.wordFormat4DB(target);
        
        assertNull(result);
      }
      
      //测试空字符串的处理情况
      @Test public void wordFormat4DBEmpty(){
        String target = "";
        String result = WordDealUtil.wordFormat4DB(target);
        
        assertEquals("", result);
      }
      //测试当首字母大写时的情况
      @Test public void wordFormat4DBegin(){
        String target = "EmployeeInfo";
        String result = WordDealUtil.wordFormat4DB(target);
        
        assertEquals("employee_info", result);
      }
      
      //测试当尾字母为大写时的情况
      @Test public void wordFormat4DBEnd(){
        String target = "employeeInfoA";
        String result = WordDealUtil.wordFormat4DB(target);
        
        assertEquals("employee_info_a", result);
      }
      
      //测试多个相连字母大写时的情况
      @Test public void wordFormat4DBTogether(){
        String target = "employeeAInfo";
        String result = WordDealUtil.wordFormat4DB(target);
        
        assertEquals("employee_a_info", result);
      }
    }

     

    6.运行Junit

    测试方法必须使用注解 org.junit.Test 修饰。

    测试方法必须使用 public void 修饰,而且不能带有任何参数。

    在测试类上点击右键,在弹出菜单中选择 Run As JUnit Test。运行结果如下图所示:

    运行界面提示我们有两个测试情况未通过测试

    ——当首字母大写时得到的处理结果与预期的有偏差,造成测试失败(failure);——而当测试对 null 的处理结果时,则直接抛出了异常测试错误(error

     

    JUnit 将测试失败的情况分为两种:failure errorFailure 一般由单元测试使用的断言方法判断失败引起,它表示在测试点发现了问题;而 error 则是由代码异常引起,这是测试目的之外的发现,它可能产生于测试代码本身的错误(测试代码也是代码,同样无法保证完全没有缺陷),也可能是被测试代码中的 一个隐藏的bug

     

    7. 测试套件

    创建一个空类作为测试套件的入口。

    使用注解 org.junit.runner.RunWith org.junit.runners.Suite.SuiteClasses 修饰这个空类。

    org.junit.runners.Suite 作为参数传入注解 RunWith,以提示 JUnit 为此类使用套件运行器执行。

    将需要放入此测试套件的测试类组成数组作为注解 SuiteClasses 的参数。

    保证这个空类使用 public 修饰,而且存在公开的不带有任何参数的构造函数。

    package com.ai92.cooljunit;
    import org.junit.runner.RunWith;
    import org.junit.runners.Suite;
    ……
    /**
    *
    批量测试 工具包 中测试类
    * @author Ai92
    */
    @RunWith(Suite.class)
    @Suite.SuiteClasses({xx1.class, xx2.class})
    public class RunAllUtilTestsSuite {
    }

Open Toolbar