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

    一、单元测试的好处

      单元测试可以帮助我们验证程序的逻辑是否正确、可以降低bug修复的成本、更有利于代码重构等等。所以,我们在写代码的时候,尽量保证单元测试的覆盖率。能力好的可以先写测试用例,再写功能代码(测试先行)。

    二、使用JUnit

      1、JUnit框架:JUnit是一个托管在Github上的开源项目,是Java程序员使用率最高的测试框架,使用@Test注释来标识指定测试的方法。

      2、怎么在JUnit中进行测试呢(以maven项目为例):首先在pom中引入JUnit的依赖,然后在src/test/java中建立相关测试类,编写测试用例方法,在方法上添加@Test,并在方法内使用合适的assert进行判断,运行即可。实例如下:

    public class MyTest001 {
        @Test
        public void test001(){
            Assert.assertEquals(1,1);
        }
    }

      3、命名约定:

        ①在/src/test/java中建立与/src/main/java相对应的测试类,以Test为后缀。

        ②测试名称应该见名知意,一般使用多should、when、then等单词。

      4、JUnit4中常用的注释

    @Test 将方法标识为测试方法,还可以有expected和timeout两个属性
    @Test(expected = Exception.class) 如果方法不抛出指定的异常,则失败
    @Test(timeout = 100) 如果方法花费的时间超过100毫秒,则会失败
    @Before 在测试方法执行之前,先执行被@Before标记的方法,用于准备测试环境,如初始化类等。
    @After 在测试方法执行之后执行,用于清理测试环境,如删除临时数据等。
    @BeforeClass 在所有测试开始之前执行一次,用于执行时间密集型活动,如数据库连接。被@BeforeClass标记的方法需要是static修饰
    @AfterClass 在所有测试完成后执行一次。用于执行清理活动,如断开与数据库的连接。被@AfterClass标记的方法需要是static修饰
    @Ignore 标记应禁用测试。当底层代码已更改且测试用例尚未调整时,非常有用。最好描述禁用原因。

    代码示例:

    public class MyTest001 {
    
        @BeforeClass
        public static void beforeClass(){
            System.out.println("MyTest001.beforeClass ...");
        }
    
        @Before
        public void before(){
            System.out.println("MyTest001.before...");
        }
    
        @Test
        public void test001(){
            System.out.println("MyTest001.test001...");
            Assert.assertEquals(1,1);
        }
    
        @Test
        @Ignore("测试用例没有修改...")
        public void test002(){
            System.out.println("MyTest001.test002...");
            Assert.assertEquals(1,1);
        }
    
        @After
        public void after(){
            System.out.println("MyTest001.after...");
        }
    
        @AfterClass
        public static void afterClass(){
            System.out.println("MyTest001.afterClass ...");
        }
    
    }

     运行结果如下:

        

      5、JUnit4断言

        JUnit通过Assert类提供的静态方法来测试某些条件。这些断言语句通常是以assert开头。可以指定错误信息、预期结果和实际结果。断言方法将测试返回的实际值和预期值进行比较。如果比较失败,将抛出java.lang.AssertionError异常。

        常用断言如下,[message]参数可选:

    fail([String message]) 让测试方法失败。
    assertTrue([String message,] boolean condition) 检查布尔条件是否为true。对应方法名称assertFalse

    assertEquals([String message,] 多种类型 unexpected,
    多种类型 actual)

    测试两个值是否相同。对应方法名称assertNotEquals。

    assertEquals([String message,] double/float expected,
    double/float actual, double/float delta)

    测试float或double值是否匹配。容差是必须相同的小数位数。对应方法名称assertNotEquals。
    assertNull([String message,] Object object) 检查对象是否为空。对应方法名称assertNotNull。
    assertSame([String message,]Object expected, Object actual) 检查两个变量是否引用同一个对象。对应方法名称assertNotSame

    assertArrayEquals([String message,] 各种类型[] expecteds,
    各种类型[] actuals)

    检查数组内容是否相同。

    assertArrayEquals([String message,] double/float[] expecteds,
    double/float[] actuals, double/float delta)

    检查double/float数组内容是否相同,指定容差范围。

    assertThat([String message, ]T actual, Matcher matcher)

    actual为需要测试的变量,matcher为使用Hamcrest的匹配符来表达变量actual期望值的声明。(其实内部调用的是org.hamcrest.MatcherAssert.assertThat)

      

      6、测试类中测试方法的执行顺序

        测试类中的测试方法,也是可以指定按方法名称的字典顺序执行的,在测试类上添加@FixMethodOrder注解,有三个值可选分别是:MethodSorters.DEFAULT:默认执行顺序,由方法名hashcode值来决定,如果hash值大小一致,则按名字的字典顺序确定;MethodSorters.NAME_ASCENDING:按方法名称的字典顺序;MethodSorters.JVM:按JVM返回的方法名的顺序执行。示例代码如下:

    /**
     * @FixMethodOrder指定测试方法执行顺序
     * MethodSorters.DEFAULT:默认执行顺序,由方法名hashcode值来决定,如果hash值大小一致,则按名字的字典顺序确定。
     * MethodSorters.NAME_ASCENDING:按方法名称的字典顺序。
     * MethodSorters.JVM:按JVM返回的方法名的顺序执行。
     */
    @FixMethodOrder(MethodSorters.JVM)
    public class MyTest003 {
    
        @Test
        public void testCThird(){
            System.out.println("MyTest003.testCThird");
        }
    
        @Test
        public void testAFirst(){
            System.out.println("MyTest003.testAFirst");
        }
    
        @Test
        public void testBSecond(){
            System.out.println("MyTest003.testBSecond");
        }
    
    }

    运行结果:MethodSorters.DEFAULT        

         MethodSorters.NAME_ASCENDING   

         MethodSorters.JVM          

      7、JUnit测试套件

        我们可以将几个测试类组合到一个测试套件中,根据填写的顺序运行测试类。

    /**
     * 使用@Suite.SuiteClasses可以将多个测试类放到一起进行测试,也可以包含其他被@Suite.SuiteClasses标记的类
     * 以指定的顺序运行套件中的所有测试类。
     */
    @RunWith(Suite.class)
    @Suite.SuiteClasses({MyTest001.class,MyTest002.class,MyTest003.class})
    public class AllTests {
    }

      8、分类测试

        我们还可以定义测试类别,并根据注释包含或排除它们。

    public interface FastTests {
        /* 类别标记 */
    }
    
    public interface SlowTests {
        /* 类别标记 */
    }
    
    public class A {
    
        @Test
        public void a() {
            fail();
        }
    
        /**
         * 该方法属于SlowTests类别
         */
        @Test
        @Category(SlowTests.class)
        public void b() {
        }
    
    }
    
    /**
     * 该测试类属于SlowTests、FastTests两种类别
     */
    @Category({SlowTests.class, FastTests.class})
    public class B {
    
        @Test
        public void c() {
        }
    }
    
    /**
     * 分类别运行测试用例
     */
    @RunWith(Categories.class)
    @Categories.IncludeCategory(SlowTests.class)  //指定包含的类别
    @Categories.ExcludeCategory(FastTests.class) //指定排除的类别
    @Suite.SuiteClasses( { A.class, B.class }) // 类别是一种套件
    public class SlowTestSuite {
        // 不打开注释@Categories.ExcludeCategory,将会运行 A.b and B.c, 不会运行 A.a
        // 打开注释@Categories.ExcludeCategory,将会运行 A.b
    }

      8、JUnit参数化测试:https://github.com/Pragmatists/JUnitParams

      9、JUnit规则:https://github.com/junit-team/junit4/wiki/Rules

  • 相关阅读:
    python第三十一课--递归(1.简单递归函数的定义和使用)
    python第三十课--异常(with as操作)
    python第三十课--异常(异常对象传递过程)
    python第三十课--异常(raise关键字)
    python第三十课--异常(else讲解)
    python第三十课--异常(finally讲解)
    python第三十课--异常(异常处理定义格式和常见类型)
    python第二十九课——文件读写(复制文件)
    python第二十九课——文件读写(写数据的操作)
    16 nginx实现负载均衡
  • 原文地址:https://www.cnblogs.com/caofanqi/p/10820425.html
Copyright © 2011-2022 走看看