欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

单元测试_JUnit常用单元测试注解介绍及代码演示

程序员文章站 2022-03-24 10:57:48
JUnit常用单元测试注解介绍及代码演示 by:授客 QQ:1033553122 1. 测试环境 1 2. 基础概念 1 3. 常用Annotation 1 4. 运行环境配置 3 maven配置 3 Eclipse maven运行环境配置 4 更新项目 5 5. 单元测试实践 7 被测类Binar ......

junit常用单元测试注解介绍及代码演示

 

by:授客 qq:1033553122

1. 测试环境 1

2. 基础概念 1

3. 常用annotation 1

4. 运行环境配置 3

maven配置 3

eclipse maven运行环境配置 4

更新项目 5

5. 单元测试实践 7

被测类binarysearch 7

测试类binarysearchtest 8

被测类caculator 11

测试类caculatortest 12

测试套件类runalltestclass 13

运行单元测试 13

运行结果展示 16

 

1. 测试环境

win7

 

eclipse-java-oxygen-3a-win32-x86_64.zip

 

apache-maven-3.5.4-bin.zip

https://pan.baidu.com/s/1ounc0kznduxjjlbpw76gza

 

 

2. 基础概念

测试方法 :用@test注解修饰的一些类方法。

测试类:包含一个或多个测试方法的java类;

测试套件:用@runwith(suite.class) 及@suiteclasses注解的;font-size:10.5000pt;mso-font-kerning:0.0000pt;">一个或多个测试类

 

 

3. 常用annotation

 

@runwith  修饰测试类,用于修改运行器,如果不指定@runwith则使用默认运行器。当测试类被@runwith注解修饰时,或者类继承了一个被该注解修饰的类,junit将会使用这个注解所指明的运行器来运行单元测试,而不使用junit默认的运行器。

 

常见的运行器有: 

@runwith(junit4.class)  junit4的默认运行器

 

@runwith(springrunner.class)  集成了spring的一些功能的运行器

 

@runwith(suite.class)  配合@suiteclasses使用,用于执行测试套件的运行器  

 

@runwith(parameterized.class)   参数化运行器,配合@parameters使用,参数化运行单元测试,需要在被修饰的测试类中的,提供数据的方法上加上一个@parameters注解,例如,注意,这个提供数据的方法必须是静态的(static),并且返回一个集合(collection)

 

我们可以为@parameters 提供一个“名称”,以便更清晰的标记每个测试方法在每次运行时所使用的参数

 

“名称”可以包含占位符,该占位符在运行时将会被替换。

·{index}: 当前参数的索引

·{0}, {1}, …: 第一个参数,第二个参数等对应的参数值。

 

 

 

@test  注解将一个普通方法修饰为一个测试方法,可选参数 timeout、expected,如下:

@test(timeout = 1000)  设置被修饰的测试方法在预期时间(例中为 1000毫秒)内执行完成,否则测试失败;

 

@test(expected = exception.class)设置被修饰的测试方法应该抛出的预期异常,异常类型为:exception.class,如果测试方法没有抛出预期的异常,则测试失败, 例如 @test(expected = nullpointexception.class)

 

注意:测试方法必须是public void,即公共、无返回

 

参考链接:

 

 

 

@beforeclass  注解用于修饰测试类中的非测试方法,该方法将在其所属测试类中的所有测试方法被执行前运行,且只运行一次,可用于做一些测试基础准备,比如数据库连接,读取文件等。

 

注意:@beforeclass修饰的方法必须是被public static void 修饰的方法,即公开、静态、无返回

 

 

 

@afterclass  同@beforeclass相反,注解用于修饰测试类中的非测试方法,该方法将在其所属测试类中所有测试方法执行完成后被运行,且只运行一次,可用于做一些测试后续操作,比如断开数据库连接,关闭文件等。

 

注意:@afterclass 修饰的方法必须是被public static void 修饰的方法,即公开、静态、无返回

 

 

 

@before 注解用于修饰测试类中的非测试方法, 该方法会在其所属测试类中的每一个测试方法运行前运行一次

 

与@beforeclass的区别在于,@before不止运行一次,它会在每个测试方法运行之前都运行一次。主要用于为单个测试方法做一些基础的测试准备工作。

 

注意:@before 修饰的方法必须是被public void 修饰的方法,即公开、无返回,但不能是被static修饰的

 

 

 

@after:用于修饰测试类中的非测试方法, 同@before相反,该方法会在其所属测试类中的每一个测试方法执行完后都运行一次

 

注意:@after 修饰的方法必须是被public void 修饰的方法,即公开、无返回,但不能是被static修饰的

 

 

 

@ignore    注释掉一个测试方法或一个类,被注释的方法或类,不会被执行;

 

 

 

4. 运行环境配置

maven配置

确保安装了java jdk并正确设置了java_home

下载bin.zip压缩包,解压到目标路径(例中 d:\program files\apache-maven-3.5.4\

),设置maven_home及path环境变量,如下

单元测试_JUnit常用单元测试注解介绍及代码演示

 




 

 

cmd输入mvn -v测试

单元测试_JUnit常用单元测试注解介绍及代码演示

 



 

 

eclipse maven运行环境配置

如图,window - preferences - maven -user settings,browse指定maven配置文件所在路径


单元测试_JUnit常用单元测试注解介绍及代码演示

 



 

更新项目

为了解决项目jar包依赖之类的问题,更新项目,右键项目根目录 - maven - update project


单元测试_JUnit常用单元测试注解介绍及代码演示

 




 

 

如下图,默认已经选中了工程项目,默认选项配置的基础上,勾选上“force update of snapshots/releases”,ok提交

单元测试_JUnit常用单元测试注解介绍及代码演示

 

 

5. 单元测试实践

被测类binarysearch

 

package org.shouke.demo;

 

public class binarysearch {

 

    public int binarysearch(long[] a, long key) {

        int low = 0;

        int high = a.length - 1;

        

        while (low <= high) {

            int mid = (low + high) >>> 1;

            

            long midval = a[mid];

            

            if (midval < key)

                low = mid + 1;

            else if (midval > key)

                high = mid - 1;

            else

                return mid;

        }

        return -1;

    }

    

 

}

 

测试类binarysearchtest

 

package org.shouke.test;

 

import org.junit.after;

import org.junit.afterclass;

import org.junit.assert;

import org.junit.ignore;

import org.junit.test;

import org.junit.before;

import org.junit.beforeclass;

import org.junit.runner.runwith;

import org.junit.runners.junit4;

 

import org.shouke.demo.binarysearch;

 

//@runwith(springrunner.class)

@runwith(junit4.class)

//@springboottest

//@testpropertysource("classpath:test-application.properties")

public class binarysearchtest {

 

    private binarysearch binarysearch = new binarysearch();

 

    private long[] array1 = new long[] {};

 

    

    @test

    public void testbinarysearch1() {

        system.out.println("执行方法 testbinarysearch1");

 

     int index = binarysearch.binarysearch(array1, 401l);

        assert.assertequals(-1, index);

 

    }

 

    private long[] array2 = new long[] {123l,123l,123l,123l,123l,123l,123l,123l};

    

    @ignore

    public void testbinarysearch2() {

        system.out.println("执行方法 testbinarysearch2");

     int index = binarysearch.binarysearch(array2, 401l);

        assert.assertequals(-1, index);

    }

   

  private long[] array3 = new long[] {123l, 456l};

  

  

  @test

  public void testbinarysearch3() {

      system.out.println("执行方法 testbinarysearch3");

  int index = binarysearch.binarysearch(array3, 401l);

      assert.assertequals(-1, index);

  }

 

  private long[] array4 = new long[] {123l, 456l};

  

  

  @test

  public void testbinarysearch4() {

      system.out.println("执行方法 testbinarysearch4");

      

      int index = binarysearch.binarysearch(array4, 40l);

      assert.assertequals(-1, index);

  }

  

  

  private long[] array5 = new long[] {123l, 456l};

  

  @test

  public void testbinarysearch5() {

      system.out.println("执行方法 testbinarysearch5");

 

  int index = binarysearch.binarysearch(array5, 123l);

      assert.assertequals(0, index);

  }

  

  private long[] array6 = new long[] {123l, 123l};

  

  @test

  public void testbinarysearch6() {

      system.out.println("执行方法 testbinarysearch6");

 

  int index = binarysearch.binarysearch(array6, 123l);

      assert.assertequals(0, index);

  }

  

 

  

  

  @before

  public void testbeforemethod() {

      system.out.println("执行每个方法前先执行该函数");

  }

  

  

  

  @after

  public void testaftermethod() {

      system.out.println("执行完每个方法后都会执行该函数");

  }

  

 

  

  @beforeclass

  public static void testbeforeclass() {

      system.out.println("执行测试类的所有方法前先执行该函数");

  }

  

  

  

  @afterclass

  public static void testafterclass() {

      system.out.println("执行完测试类的所有方法后都会执行该函数");

  }

  

 

}

 

 

被测类caculator

package org.shouke.demo;

 

 

public class caculator {

 

    public int caculate(int arg1, int arg2) {

        if (arg1 > arg2) {

         return arg1 - arg2;

        } else if (arg1 < arg2) {

         return arg1 + arg2;

        } else {

         return arg1;

        }

 

    }

    

 

}

 

测试类caculatortest

package org.keshou.test;

 

import org.junit.assert;

import org.junit.test;

import org.junit.runner.runwith;

import org.junit.runners.parameterized;

 

import org.shouke.demo.caculator;

import java.util.arrays;

import java.util.collection;

 

@runwith(parameterized.class)

public class caculatortest {

 

    private caculator caculator = new caculator();

 

    public int arg1;

    public int arg2;

    

    public caculatortest(int arg1, int arg2) {

     this.arg1 = arg1;

     this.arg2 = arg2;

    }

    

//  @parameterized.parameters

    @parameterized.parameters(name = "{index}: (arg1: {0} arg2: {1}")

    public static collectiondata() {

       return arrays.aslist(new object[][] {

               { 10, 1}, { 5, 1 }

       });

    }

 

  

  

    @test

    public void testcaculate1() {

     int result = caculator.caculate(arg1, arg2);

     system.out.println("执行方法 testcaculate1  参数:" + arg1 + " " + arg1);

     assert.assertequals(result, arg1-arg2);

    }

 

 

    @test

    public void testcaculate2() {

     int result = caculator.caculate(arg1, arg2);

     system.out.println("执行方法 testcaculate2   参数:" + arg1 + " " + arg1);

     assert.assertequals(result, arg1+arg2);

    }

}

 

说明:被@parameters 注解修饰用于提供参数的方法有多少个参数,那么就需要为其所在类提供对应数量的类属性,及一个包含对应数量的参数的构造函数,否则会报错:java.lang.illegalargumentexception: wrong number of arguments

 

 

 

测试套件类runalltestclass

package org.keshou.test;

 

import org.junit.runner.runwith;

import org.junit.runners.suite;

 

 

@runwith(suite.class)

@suite.suiteclasses({caculatortest.class, org.shouke.test.binarysearchtest.class})

public class runalltestclass {

 

}

 

说明:如果需要运行多个测试类,只需要把目标测试类名称.class放入如下的 {}中即可,测试类之间使用逗号分隔,如果不是同一个包中的测试类,记得加上对应的package名称,或者使用import提前导入对应类。

 

@suite.suiteclasses({a.class, b.class, ...})

 

 

 

运行单元测试

如下图,右键整个项目、单个测试类、测试套件 ->  coverage as  ->  junit test

 

或者

如下图,右键整个项目、单个测试类、测试套件 -> run as  ->  junit test

单元测试_JUnit常用单元测试注解介绍及代码演示

 

 单元测试_JUnit常用单元测试注解介绍及代码演示

 

 单元测试_JUnit常用单元测试注解介绍及代码演示

 

 

 

说明:

1、如果右键时选择的是整个项目,那么项目src\test\;font-size:10.5000pt;mso-font-kerning:0.0000pt;">目录下的都有测试类都会被执行。

 

2、coverage as 和 run as 这两种运行方式的区别在于前者运行完成,会在控制台端自动打开 coverage 界面,展示覆盖率,后者需要手动打开,打开方式如下:

window -> show view -> java -> coverage


单元测试_JUnit常用单元测试注解介绍及代码演示

 

 

 

运行结果展示

 

运行测试套件


单元测试_JUnit常用单元测试注解介绍及代码演示

 

单元测试_JUnit常用单元测试注解介绍及代码演示