zoukankan      html  css  js  c++  java
  • 单元测试_JUnit常用单元测试注解介绍及代码演示

    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://maven.apache.org/download.cgi

    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,即公共、无返回

     

    参考链接:https://www.cnblogs.com/mengdd/archive/2013/04/13/3019278.html

     

     

     

    @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 Filesapache-maven-3.5.4

    ),设置MAVEN_HOME及Path环境变量,如下




     

     

    cmd输入mvn -v测试



     

     

    Eclipse maven运行环境配置

    如图,Window - Preferences - Maven -User Settings,Browse指定maven配置文件所在路径




     

    更新项目

    为了解决项目jar包依赖之类的问题,更新项目,右键项目根目录 - Maven - Update Project





     

     

    如下图,默认已经选中了工程项目,默认选项配置的基础上,勾选上“Force Update of Snapshots/Releases”,OK提交

     

    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

     

     

     

     

    说明:

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

     

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

    Window -> Show View -> Java -> Coverage


     

     

    运行结果展示

     

    运行测试套件




     

     

  • 相关阅读:
    Java操作符,<<、>>等
    abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
    使用JDBC连接各种数据库
    pt-online-schema-change的原理解析与应用说明
    MySQL Online DDL的改进与应用
    细细探究MySQL Group Replicaiton — 配置维护故障处理全集
    关于binary log那些事——认真码了好长一篇
    梳理下MySQL崩溃恢复过程
    说说MySQL中的Redo log Undo log都在干啥
    SQL SERVER大话存储结构(5)_SQL SERVER 事务日志解析
  • 原文地址:https://www.cnblogs.com/shouke/p/10171253.html
Copyright © 2011-2022 走看看