IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 18.单元测试 -> 正文阅读

[开发测试]18.单元测试

单元测试

单元测试是针对最小的功能单元编写测试代码
Java程序最小的功能单元是方法,对Java程序进行单元测试就是针对单个Java方法的测试
测试驱动开发TDD是一种根据功能实现代码的开发模式

JUnit

Java平台最常用的测试框架JUnit是一个开源的Java语言的单元测试框架,专门针对Java设计,使用最广泛
编写了一个xxx.java文件后,我们想对其进行测试,需要编写一个对应的xxxTest.java文件,以Test为后缀是一个惯例,并分别将其放入src和test目录中
一个JUnit测试包含若干@Test方法,并使用Assertions进行断言,核心测试方法testFact()要加上@Test注解,JUnit会把带有@Test的方法识别为测试方法。Assertion定义的用于测试的断言方法包括:

  • assertEquals(expected, actual):期待actual结果等于expected
  • assertTrue(): 期待结果为true
  • assertFalse(): 期待结果为false
  • assertNotNull(): 期待结果为非null
  • assertArrayEquals(): 期待结果为数组并与期望数组每个元素的值均相等

如果测试结果与预期不符,assertEquals()会抛出异常,我们就会得到一个测试失败的结果
单元测试可以确保单个方法按照正确预期运行,如果修改了某个方法的代码,只需确保其对应的单元测试通过,即可认为改动正确。此外,测试代码本身就可以作为示例代码,用来演示如何调用该方法。
使用断言(Assertion)来测试期望结果,可以方便地组织和运行测试,并方便地查看测试结果。此外,JUnit既可以直接在IDE中运行,也可以方便地集成到Maven这些自动化工具中运行。

单元测试需遵循规范:

  • 单元测试代码本身必须非常简单,能一下看明白,决不能再为测试代码编写测试
  • 每个单元测试应当互相独立,不依赖运行的顺序
  • 测试时不但要覆盖常用测试用例,还要特别注意测试边界条件,例如输入为0,null,空字符串""等情况

Fixture

在一个单元测试中,经常编写多个@Test方法,来分组、分类对目标代码进行测试。在测试的时候,经常遇到一个对象需要初始化,测试完可能还需要清理。JUnit提供了编写测试前准备、测试后清理的固定代码,我们称之为Fixture
编写Fixture是指针对每个@Test方法,编写@BeforeEach方法用于初始化测试资源,编写@AfterEach用于清理测试资源;必要时,可以编写@BeforeAll和@AfterAll,使用静态变量来初始化耗时较长的资源,并且在所有@Test方法的运行前后仅执行一次。Test结构如下

invokeBeforeAll(CalculatorTest.class);
for (Method testMethod : findTestMethods(CalculatorTest.class)) {
    var test = new CalculatorTest(); // 创建Test实例
    invokeBeforeEach(test);
        invokeTestMethod(test, testMethod);
    invokeAfterEach(test);
}
invokeAfterAll(CalculatorTest.class);

对于实例变量,在@BeforeEach中初始化,在@AfterEach中清理,它们在各个@Test方法中互不影响,因为是不同的实例;对于静态变量,在@BeforeAll中初始化,在@AfterAll中清理,它们在各个@Test方法中均是唯一实例,会影响各个@Test方法。
大多数情况下,使用@BeforeEach和@AfterEach足够。只有某些测试资源初始化耗费时间太长,以至于我们不得不尽量“复用”时才会用到@BeforeAll和@AfterAll。
最后,注意到每次运行一个@Test方法前,JUnit首先创建一个XxxTest实例,因此,每个@Test方法内部的成员变量都是独立的,不能也无法把成员变量的状态从一个@Test方法带到另一个@Test方法

异常测试

在编写JUnit测试的时候,除了正常的输入输出,我们还要特别针对可能导致异常的情况进行测试。测试异常可以使用assertThrows(),期待捕获到指定类型的异常;对可能发生的每种类型的异常都必须进行测试。
JUnit提供assertThrows()来期望捕获一个指定的异常。第二个参数Executable封装了我们要执行的会产生异常的代码。当我们执行测试代码并抛出IllegalArgumentException时,assertThrows()在捕获到指定异常时表示通过测试,未捕获到异常,或者捕获到的异常类型不对,均表示测试失败。

条件测试

条件测试是根据某些注解在运行期让JUnit自动忽略某些测试。JUnit根据不同的条件注解,决定是否运行当前的@Test方法。例如
@Disabled:JUnit仍然识别出这是个测试方法,只是暂时不运行
@EnableOnOs:在某个系统运行
@DisabledOnOs(OS.WINDOWS):不在Windows平台执行的测试
@DisabledOnJre(JRE.JAVA_8):只能在Java 9或更高版本执行的测试
@EnabledIfSystemProperty(named = “os.arch”, matches = “.64.”):只能在64位操作系统上执行的测试
@EnabledIfEnvironmentVariable(named = “DEBUG”, matches = “true”):需要传入环境变量DEBUG=true才能执行的测试

参数化测试

如果待测试的输入和输出是一组数据: 可以把测试数据组织起来 用不同的测试数据调用相同的测试方法
参数化测试下,一个测试方法需要接收至少一个参数,然后传入一组参数反复运行。
JUnit提供了一个@ParameterizedTest注解,用来进行参数化测试。

参数如何传递?既可以在测试代码中写死,也可以通过@CsvFileSource放到外部的CSV文件中。

  • 通过@MethodSource注解,允许我们编写一个同名的静态方法来提供测试参数
@ParameterizedTest
@MethodSource
void testCapitalize(String input, String result) {
    assertEquals(result, StringUtils.capitalize(input));
}

static List<Arguments> testCapitalize() {
    return List.of( // arguments:
            Arguments.arguments("abc", "Abc"), //
            Arguments.arguments("APPLE", "Apple"), //
            Arguments.arguments("gooD", "Good"));
}
  • 使用@CsvSource,它的每一个字符串表示一行,一行包含的若干参数用,分隔
@ParameterizedTest
@CsvSource({ "abc, Abc", "APPLE, Apple", "gooD, Good" })
void testCapitalize(String input, String result) {
    assertEquals(result, StringUtils.capitalize(input));
}
  • 可以把测试数据提到一个独立的CSV文件中,然后标注上@CsvFileSource,JUnit只在classpath中查找指定的CSV文件,因此,test-capitalize.csv这个文件要放到test目录下
@ParameterizedTest
@CsvFileSource(resources = { "/test-capitalize.csv" })
void testCapitalizeUsingCsvFile(String input, String result) {
    assertEquals(result, StringUtils.capitalize(input));
}
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-10-17 12:16:56  更:2021-10-17 12:17:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 2:43:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码