Junit学习笔记(1) – 安装插件&基本使用

background: JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks.

usage: Junit4

进行以下实验的pom.xml:

<dependencies>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>com.hynnet</groupId>
        <artifactId>json-lib</artifactId>
        <version>2.4</version>
    </dependency>
</dependencies>

1.安装JUnit插件步骤(适用于IDEA)              

File–>settings–>Plguins–>Browse repositories–>输入JUnit–>选择JUnit Generator V2.0安装。 2.配置JUnit插件 File –> settings –> JUnit Generator –>properties 修改output path为 ${SOURCEPATH}/../test/${PACKAGE}/${FILENAME} (以上主要为了保证结构如下图)

qq%e5%9b%be%e7%89%8720161025121910

同时修改JUnit Generator –> junit 4下的模板为以下(主要是调整了格式和由于output path调整后的package声明问题):

######################################################################################## 
## 
## Available variables: 
##         $entryList.methodList – List of method composites 
##         $entryList.privateMethodList – List of private method composites 
##         $entryList.fieldList – ArrayList of class scope field names 
##         $entryList.className – class name 
##         $entryList.packageName – package name 
##         $today – Todays date in MM/dd/yyyy format 
## 
##            MethodComposite variables: 
##                $method.name – Method Name 
##                $method.signature – Full method signature in String form 
##                $method.reflectionCode – list of strings representing commented out reflection code to access method (Private Methods) 
##                $method.paramNames – List of Strings representing the method's parameters' names 
##                $method.paramClasses – List of Strings representing the method's parameters' classes 
## 
## You can configure the output class name using "testClass" variable below. 
## Here are some examples: 
## Test${entry.ClassName} – will produce TestSomeClass 
## ${entry.className}Test – will produce SomeClassTest 
## 
######################################################################################## 
## 
#macro (cap $strIn)$strIn.valueOf($strIn.charAt(0)).toUpperCase()$strIn.substring(1)#end 
## Iterate through the list and generate testcase for every entry. 
#foreach ($entry in $entryList) 
#set( $testClass="${entry.className}Test") 
## 
package $entry.packageName; 

import org.junit.Test; 
import org.junit.Before; 
import org.junit.After; 

/** 
* ${entry.className} Tester. 

* @author <Authors name> 
* @since <pre>$date</pre> 
* @version 1.0 
*/ 
public class $testClass { 

    @Before
    public void before() throws Exception { 
    } 
    
    @After
    public void after() throws Exception { 
    } 

#foreach($method in $entry.methodList) 
    /** 
    * 
    * Method: $method.signature 
    * 
    */ 
    @Test
    public void test#cap(${method.name})() throws Exception { 
    //TODO: Test goes here… 
    } 

#end 

#foreach($method in $entry.privateMethodList) 
    /** 
    * 
    * Method: $method.signature 
    * 
    */ 
    @Test
    public void test#cap(${method.name})() throws Exception { 
    //TODO: Test goes here… 
#foreach($string in $method.reflectionCode) 
    $string 
#end 
    } 

#end 

#end

 

整个结构就是:

Src/main

Src/main/java/packageName/xxxx.java

Src/main/test/packageName/xxxxTest.java

 

 3.使用JUnit插件

             在需要进行单元测试的类中,使用快捷键alt+insert,选择JUnit test,选择JUnit4,就会帮你自动生成当前class的所有对应测试方法(body为空)

 

 4.一个简单的示例

以下是一个加法的类,实现了Double类型的加法和乘法

package Operations;

/**
 * Project Name : junitTest
 * Package Name : Operations
 * Created by chingzhu on 2016/10/11.
 */
public class Operation {

    public static Double add(Double i, Double j){
        return i+j;
    }
    public static Double times(Double i, Double j){
        return i*j;
    }
}

通过快捷键alt + insert,选择Junit4,则自动会生成以下测试:(我已补充测试方法)

package Operations;

import org.junit.Test; 
import org.junit.Before; 
import org.junit.After;

import static org.junit.Assert.assertEquals;

/** 
* Operation Tester.
* 
* @author <Authors name> 
* @since <pre>10, 11, 2016</pre>
* @version 1.0 
*/ 
public class OperationTest {

    @Before
    public void before() throws Exception {
    }

    @After
    public void after() throws Exception {
    }

    /**
     *
     * Method: add(Double i, Double j)
     *
     */
    @Test
    public void testAdd() throws Exception {
        Double result = 2.0;
        Double x = 1.0;
        Double y = 1.0;
        assertEquals(Operation.add(x, y), result);
    }

    /**
     *
     * Method: times(Double i, Double j)
     *
     */
    @Test
    public void testTimes() throws Exception {
        Double result = 1.44;
        Double x = 1.2;
        assertEquals(Operation.times(x, x), result);
    }


} 

 

讲讲这里面的一些注解和方法的使用:

首先是断言,其实可以参考梁哥之前的文章,我罗列以下我觉得经常可能使用的:

assertEquals

函数原型1:assertEquals([String message],expected,actual)

参数说明:message是一个可选的消息,如果提供,将会在发生错误时报告这个消息。

          expected是期望值,通常都是用户指定的内容。

          actual是被测试的代码返回的实际值。

函数原型2:assertEquals([String message],expected,actual,tolerance)

参数说明:message是一个可选的消息,如果提供,将会在发生错误时报告这个消息。

          expected是期望值,通常都是用户指定的内容。

          actual是被测试的代码返回的实际值。

          tolerance是误差参数,参加比较的两个浮点数在这个误差之内则会被认为是

相等的。

 

assertTrue 

函数原型:assertTrue ([String message],Boolean condition)

参数说明:message是一个可选的消息,如果提供,将会在发生错误时报告这个消息。

          condition是待验证的布尔型值。

该断言用来验证给定的布尔型值是否为真,如果结果为假,则验证失败。当然,还有验证为假的测试条件:

函数原型:assertFalse([String message],Boolean condition)

该断言用来验证给定的布尔型值是否为假,如果结果为真,则验证失败。

同理还有assertFalse

 

assertNull

函数原型:assertNull([String message],Object object)

参数说明:message是一个可选的消息,如果提供,将会在发生错误时报告这个消息。

          object是待验证的对象。

该断言用来验证给定的对象是否为null,如果不为null,则验证失败。相应地,还存在可以验证非null的断言:

函数原型:assertNotNull([String message],Object object)

该断言用来验证给定的对象是否为非null,如果为null,则验证失败。

 

assertSame

函数原型:assertSame ([String message], expected,actual)

 

参数说明:message是一个可选的消息,如果提供,将会在发生错误时报告这个消息。

          expected是期望值。

          actual是被测试的代码返回的实际值。

该断言用来验证expected参数和actual参数所引用的是否是同一个对象,如果不是,则验证失败。相应地,也存在验证不是同一个对象的断言:

函数原型:assertNotSame ([String message], expected,actual)

该断言用来验证expected参数和actual参数所引用的是否是不同对象,如果所引用的对象相同,则验证失败。

 

Fail

函数原型:Fail([String message])

参数说明:message是一个可选的消息,如果提供,将会在发生错误时报告这个消息。

该断言会使测试立即失败,通常用在测试不能达到的分支上(如异常)。

 

此外在补充一个JsonAssert:

@Test
public void testGetJson() throws Exception { 
    //TODO: Test goes here...
    String expected =  "{\"key1\":\"value1\",\"key2\":\"value2\"}";
    JSONAssert.assertEquals(expected, <JSON Object>);
} 

这个是net.sf.json.test.JSONAssert(我司用的json那个包里提供的),可以方便的比较两个JSON Object是否相等(key和value)

 

几个常用注解:

1. @Test : 测试方法,测试程序会运行的方法,后边可以跟参数代表不同的测试,如(expected=XXException.class) 异常测试,(timeout=xxx)超时测试

2. @Ignore : 被忽略的测试方法

3. @Before: 每一个测试方法之前运行

4. @After : 每一个测试方法之后运行

5. @BeforeClass: 所有测试开始之前运行

6. @AfterClass: 所有测试结束之后运行

这里说说以上的一些用处,首先所有的被测试的方法要用@Test注解,其他的:

  1. 忽略某些尚未完成的方法: 如果在编写程序前做了比较好的规划,那么就事先将测试类先声明好,而在测试的时候,对于还没有编写完成的测试方法,为了避免不必要的报错,使用@Ignore来忽略。
  2. 固定代码段(fixture),由于我们会mock多组测试数据和预期结果,由于程序的设计问题我们有可能会在测试的过程中改变了一开始生成的被测试对象的属性值,造成无法多次重复测试,那么我们就需要借用@Before(在每一次测试方法执行之前都会执行的代码段)来重置我们的测试对象,用它来做一些每次测试方法执行前都需要处理的一些工作。 同理,@After是代表在每次测试方法执行完后需要进行的工作。
  3. 高级fixture: BeforeClass, AfterClass,如果你有一个大文件要在一开始测试前读,明显用Before就不是一个好的办法了,这样每一次执行测试方法都需要再读这个大文件,JUNIT的设计者考虑到了这个问题,于是有BeforeClass和AfterClass这两个注解可以使用,分别代表在测试用例初始化时执行BeforeClass,所有测试执行完毕后执行AfterClass
  4. 限时测试: 用于检测程序死循环或者作为检测是否达标的工具@Test(timeout=xxx ms)
  5. 测试异常: @Test(expected = XXXException.class) Java中的异常处理也是一个重点,因此我们经常会编写一些需要抛出异常的函数。那么,如果一个函数应该抛出异常,但是它没抛出,这就应该是一个Bug了,并JUnit也考虑到了这一点,来帮助我们找到这种Bug。例如,我们写的计算器类有除法功能,如果除数是一个0,那么必然要抛出“除0异常”。因此,我们很有必要对这些进行测试。
  6.  

注意事项:

1、测试方法上面必须使用@Test注解进行修饰。

2、测试方法必须使用public void 进行修饰,不能带有任何参数。

 

安装和基本使用我就介绍到这里了,下一篇会补充高级一点的参数化测试和打包测试。

 

3+

Junit学习笔记(1) – 安装插件&基本使用》上有3条评论

  1. 周佳萱

    感谢清姐分享,本文对单元测试工作有重要指导意义。

    在实际使用中发现的一些问题:

    根据一般做法,应将测试输出到${SOURCEPATH}/../../test/java/${PACKAGE}/${FILENAME},即test和main并列,测试代码放入/test/java。这样对称性更好,逻辑更清晰。

    文档注解 @since 的意义应该为JDK版本。

    模板中<code>//TODO: Test goes here…</code> 的"…"在windows下显示为乱码,linux不知道。可替换为"…"

     

    0
    回复
  2. 匿名

    maven项目的默认测试目录是 /src/test 也就是萱哥说的和main并列

    但是现在我们的一些项目是/src/main/test的结构 对于这些项目要改变结构可能会有些困难,在改变的过程中可能会发生一些意想不到的bug

    对于idea来说 test的结构长什么样不要紧 因为有make as testsource 这么一步 但是对于一些maven插件来说 他可能就找不到test的目录了

    所以这时候我们需要在pom中的标签中 加入 这样一行

    src/main/test

    0
    回复
    1. 匿名

      额 尖括号里面的内容被吞了 就用书名号《》代替了

      《build》
      《testSourceDirectory》src/main/test《/testSourceDirectory》
      《/build》

      0
      回复

发表评论

电子邮件地址不会被公开。

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>