JUnitJava 单元测试框架 | 学习笔记

Posted Fxtack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JUnitJava 单元测试框架 | 学习笔记相关的知识,希望对你有一定的参考价值。

Java 单元测试框架 | 学习笔记


文章目录


一. 单元测试

1. 何为单元测试

  • 单元测试是针对最小功能单元编写测试代码
  • Java 程序最小功能单元是方法
  • 单元测试针对单个 Java 方法的测试

2. 单元测试的优点

  • 确保单个方法运行正常
  • 如果修改了方法代码只需要确保其对应的单元测试通过
  • 测试代码本身可以作为示例代码
  • 可以自动化运行所有的测试并或得报告

二. 测试驱动开发 TDD(Test-Driven Development)

测试驱动开发流程

运行异常 运行正常 编写接口 编写测试 编写实现 运行测试 任务完成

三. JUnit 介绍

1. Junit 是一个开源的 Java 语言的单元测试框架

  • 针对 Java 语言设计,使用最广泛
  • JUnit 是事实上的标准单元测试框架

2. JUnit 的特点

  • 使用断言(Assertion)测试期望结果
  • 可以方便地组织和运行测试
  • 可以方便的查看测试结果
  • 常用的 IDE 都集成了 JUnit
  • 可以方便的集成到 Maven 中

四. JUnit 中的概念

  • TestCase:一个 TestCase 表示一个测试
  • TestSuite:一个 TestSuite 包含一组 TestCase ,表示一组测试
  • TestFixture:一个 TestFixture 表示一个测试环境
  • TestResult:用于收集测试结果
  • TestRunner:用于运行测试
  • TestListener:用于监听测试过程,并收集数据
  • Assert:用于断言测试结果是否正确

五. 断言测试

断言总览(未录的一些断言方法可以参见 JUnit API 的 Assert 类了解学习)

断言方法测试效果备注
assertEquals(int a, int b)测试值 a 与b是否相等该方法与多种数据类型重载,详细参见 JUnit API 的 Assert 类
assertNotEquals(int a, int b)测试值 a 与 b 是否不相等同上
assertArrayEquals(int[] a, int[] b)测试数组 a 与数组 b 是否相等。两数组必须顺、大小、值完全相同才能通过测试该方法与多种数据类型的数组重载,详细参见JUnit API 的Assert 类
assertNull(Object x)测试值 x 是否为空
assertNotNull(Object x)测试 x 是否不为空
assertTrue(boolean x) /assertFalse(boolean x)测试 x 是否为真/测试 x 为假可以书写逻辑运算表达式
assertSame(Object a, Object b)测试 a 和 b 的引用是否指向同一个对象

简单使用

  • 断言相等与不相等

    assertEquals(100, x);
    测试 x 是否值为 100

    assertNotEquals(100, x);
    测试 x 是否值不为 100

  • 断言数组相等
    assertArrayEquals(y, x);

    测试 x 是否与 y 数组相等

  • 浮点数断言相等

    assertEquals(3.1416, x, 0.0001);
    测试 x 是否在精度为 0.0001 的情况下与 3.1416 相等

  • 断言为null或不为 null
    assertNull(x);

    测试x是否为空

    assertNotNull(x);
    测试x不为空

  • 布尔值断言

    assertTrue(x>0);
    assertFalse(x<0);
    测试值为true / false

Assert测试案例

注意:JUnit以方法为测试单元,因此作为测试的方法需要加上 @Test 注解

package org.example.test

import org.junit.Test;
import static org.junit.Assert.*;

public class Test 
    //测试方法需要加上@Test注解
    @Test
    public void test1() 
        assertEquals(5,2+3);
    
    
    @Test
    pubic void test2() 
        assertEquals(3.1415926,3.1415927,0.00000001);
    

//若测试通过,控制台上将不会显示任何信息

运行以上测试方法 test2 时,测试失败,控制台将会显示以下信息:

(运行环境为 Java8,IDEA 2020。只截取了部分关键运行结果信息如下)


java.lang.AssertionError: 
Expected :3.1415926
Actual   :3.1415927
<Click to see difference>

...

六. JUnit Fixture

  • @Before@After

    每个 @Test 方法执行前都会执行 @Before 方法。主要用于创建 @Test 方法需要的一些资源。若有多个 @Test 方法,每次执行 @Test 方法前都会单独执行 @Before 方法,使得资源互不影响。@After 同理,用于关闭一些资源,在 @Test 方法完成后执行。

    package org.example.test
        
    import static org.junit.Assert.*;
    import static org.junit.Before;
    import static org.junit.After;
    
    public class Test 
        
        Main m;
        
        @Before
        public void setUp() 
            m = new Main();
        
        
        @After
        public void setDown() 
            System.out.println("A test method is finish");
        
       
        @Test
        public void testMain() 
            assertEquals(5,m.add(2,3));
        
        
    
    
  • @BeforeClass@AfterClass

    @BeforeClass 在所有测试方法执行前执行的方法,一般用于创建非常耗时的资源。

    @AfterClass 在所有测试方法执行之后执行的方法,一般用于清理资源。

总测试

package org.example.test


import static org.junit.Assert.*;
import static org.junit.*;

public class Test 
    
    @BeforeClass
    public void setUpBeforClass() 
        System.out.println("BeforeClass method is running");
    
    
    @AfterClass
    public void setDownAfterClass() 
        System.out.println("AfterClass method is running");
    
    
    @Before
    public void setUp() 
        System.out.println("	Before method is runing");
    
    
    @After
    public void setDown() 
        System.out.println("	After method is running");
    
    
    @Test
    public void TestA() 
        System.out.println("		TestA method is running");
    
    
    @Test
    public void TestB() 
        System.out.println("		TestB method is running");
    
    
    @Test
    public void TestC() 
        System.out.println("		TestC method is running");
    

测试结果

BeforeClass method is running

​ Before method is runing

​ TestA method is running

​ After method is running

​ Before method is runing

​ TestB method is running

​ After method is running

​ Before method is runing

​ TestC method is running

​ After method is running

AfterClass method is running

运行结果,方法执行顺序,图解

七. 测试异常

@Test 注释中加入参数例如:

@Test(expected = NumberFormatException.class)

表示该测试方法预期发生 NumberFormatException,若发生该异常则测试成功

八. 参数化测试

如果待测试的输入是一组数据则可以使用参数化测试,这使得测试可以用一组数据来进行多项测试

  • 可以把测试数据组织起来
  • 用不同的则是数据调用相同的测试方法
package org.example.test

import static org.junit.Assert.*;
import static org.junit.*;

@RunWith(Parameterized.class)
public class Test 
    
    private int input;
    private int expected;
    
    @Parameters
    public static Collection data() 
        //这里定义了一组测试数据
        return Arrays.asList(new Object[][] 0,0,1,1,-1,1);
    
    
    public Test(int input,int expected) 
        this.input = input;
        this.expected = expected;
    
    
    @Test
    public void testAbs() 
        //此时使用测试类的全局变量
        //将会使用 data 方法中的数据组进行逐对测试
        assertEquals(this.expected,Math.abs(this.input));
    

进行参数化测试要求:

  • 参数必须由静态方法 data() 返回
  • 返回类型为 Collection<Object[]>
  • 静态方法必须注释为 @Parameters
  • 测试类必须注释为@RunWith(Parameterized.class)
  • 构造方法参数必须和测试参数对应

九. 超时测试

在 @Test 注释中加以参数以实现执行超时测试。例如:

@Test(timeout = 500)

该方法若超过 500ms 还未完成则测试结果为超时


JUnit 4.13 API文档: https://junit.org/junit4/javadoc/latest/


文章内容来自个人学习总结
欢迎指出本笔记中存在的问题
未经本人同意禁止转载,不得用于商业用途

以上是关于JUnitJava 单元测试框架 | 学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

go语言学习笔记 — 基础 — go工具(5.1):单元测试 —— 测试和验证代码的框架

day9-Python学习笔记(二十一)单元测试

python学习笔记9-单元测试unittest

Junit单元测试学习笔记

构建之法 学习笔记04

如何创建SSM项目ssm框架整合简单开发