当前位置: 首页 > news >正文

Java IDEA JUnit 单元测试

JUnit是一个开源的 Java 单元测试框架,它使得组织和运行测试代码变得非常简单,利用JUnit可以轻松地编写和执行单元测试,并且可以清楚地看到哪些测试成功,哪些失败

JUnit 还提供了生成测试报告的功能,报告不仅包含测试的成功率,还能统计被测试代码的覆盖率。通过进行单元测试,我们可以确保每个方法按照预期正确运行。

如果我们修改了某个方法的代码,只需要确保相应的单元测试通过,就可以认为修改是正确的。此外,测试代码本身也可以作为示例代码,用于演示如何调用该方法。

几乎所有的IDE工具都集成了JUnit,我们这里使用IDEA

参考 编写JUnit测试 - 廖雪峰的官方网站 (liaoxuefeng.com)

目录

编写JUnit单元测试

使用Fixture自动执行代码

异常测试

条件测试

参数化测试

编写JUnit单元测试

用递推的方法写一个计算n的阶乘的Java方法。

我们可以针对刚刚写的Java编写一个对应的测试代码对其进行测试,在IDEA中可以直接右击点击生成Junit测试。

点击确定生成一个FactorialTest.java文件。

这是JUnit会把带有@Test的方法识别为测试方法,因此需要给测试方法加上@Test注解,测试方法内部用assertEquals(1, Factorial.fact(1))表示期望Factorial.fact(1)返回1。

运行这个测试程序,JUnit就会给出成功的测试和失败的测试,还可以生成测试报告,不仅包含测试的成功率,还可以统计测试的代码覆盖率,即被测试的代码本身有多少经过了测试。

 Factorial.java

public class Factorial {public static long fact(long n) {long r = 1;for (long i = 1; i <= n; i++) {r = r * i;}return r;}
}

 FactorialTest.java

import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test;public class FactorialTest {@Testvoid testFact() {assertEquals(1, Factorial.fact(1));assertEquals(2, Factorial.fact(2));assertEquals(6, Factorial.fact(3));assertEquals(3628800, Factorial.fact(10));assertEquals(2432902008176640000L, Factorial.fact(20));}}

使用Fixture自动执行代码

Fixture是JUnit提供的编写测试前准备、测试后清理的固定代码,可以用于测试前和测试后自动执行代码。

先编写一个简单的实现加减法功能的Calculator代码。

但是测试的时候,需要先初始化对象,可以使用@BeforeEach和@AfterEach标记的方法,@BeforeEach标记的方法会在执行每个@Test的方法之前调用,而@AfterEach标记的方法会在执行每个@Test的方法之后调用,这样就可以通过@BeforeEach和@AfterEach标记来自动实现对象的生成和销毁。

然后再编写我们的测试代码。

运行测试代码,可以看到测试结果。

如果需要在所有@Test方法运行前后仅运行一次,那么可以使用@BeforeAll和@AfterAll对方法进行标记。

 Calculator.java

public class Calculator {private long n = 0;public long add(long x) {n = n + x;return n;}public long sub(long x) {n = n - x;return n;}
}

 CalculatorTest.java

import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;public class CalculatorTest {Calculator calculator;@BeforeEachpublic void setUp() {this.calculator = new Calculator();}@AfterEachpublic void tearDown() {this.calculator = null;}@Testvoid testAdd() {assertEquals(100, this.calculator.add(100));assertEquals(150, this.calculator.add(50));assertEquals(130, this.calculator.add(-20));}@Testvoid testSub() {assertEquals(-100, this.calculator.sub(100));assertEquals(-150, this.calculator.sub(50));assertEquals(-130, this.calculator.sub(-20));}
}

异常测试

对于可能抛出的异常进行测试是测试的重要环节,因此在编写JUnit测试的时候,除了正常的输入输出,还要特别针对可能导致异常的情况进行测试。

在计算阶乘的方法中增加对参数n的检查,如果n为负数,则直接抛出异常IllegalArgumentException。

在测试代码中,我们可以编写一个@Test方法专门测试异常,JUnit提供assertThrows函数来期望捕获一个指定的异常。

运行测试代码,可以看到测试结果。

 Factorial.java

public class Factorial {public static long fact(long n) {if (n < 0) {throw new IllegalArgumentException();}long r = 1;for (long i = 1; i <= n; i++) {r = r * i;}return r;}
}

 FactorialTest.java

import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test;public class FactorialTest {@Testvoid testFact() {assertEquals(1, Factorial.fact(1));assertEquals(2, Factorial.fact(2));assertEquals(6, Factorial.fact(3));assertEquals(3628800, Factorial.fact(10));assertEquals(2432902008176640000L, Factorial.fact(20));}@Testvoid testNegative() {assertThrows(IllegalArgumentException.class, () -> {Factorial.fact(-1);});}
}

条件测试

条件测试可以在满足某种条件下执行某些测试方法,不执行某些测试方法。

编写一个程序,该程序中的方法在Windows上跑和在Linux上跑的代码路径不同。

编写测试代码的时候,用@EnableOnOs标记方法,指定只有在特定系统下才执行该测试方法。

用@DisabledOnOs标记方法表示不在某个系统上执行该方法。

用@DisabledOnJre标记方法表示只能在高于特定Java版本的测试。

用@EnabledIfSystemProperty(named = "os.arch", matches = ".*64.*")标记,表示只能在64位操作系统上执行的测试。

用@EnabledIfEnvironmentVariable标记方法表示需要传入环境变量DEBUG=true才能执行的测试。

运行测试代码,可以看到测试结果。

 Config.java

public class Config {public String getConfigFile(String filename) {String os = System.getProperty("os.name").toLowerCase();if (os.contains("win")) {return "C:\\" + filename;}if (os.contains("mac") || os.contains("linux") || os.contains("unix")) {return "/usr/local/" + filename;}throw new UnsupportedOperationException();}
}

 ConfigTest.java

import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.*;public class ConfigTest {Config config;@BeforeEachpublic void setUp() {this.config = new Config();}@AfterEachpublic void tearDown() {this.config = null;}@Test@EnabledOnOs(OS.WINDOWS)void testWindows() {assertEquals("C:\\test.ini", config.getConfigFile("test.ini"));}@Test@EnabledOnOs({OS.LINUX, OS.MAC})void testLinuxAndMac() {assertEquals("/usr/local/test.cfg", config.getConfigFile("test.cfg"));}@Test@DisabledOnOs(OS.WINDOWS)void testOnNonWindowsOs() {// TODO: this test is disabled on windows}@Test@DisabledOnJre(JRE.JAVA_8)void testOnJava9OrAbove() {// TODO: this test is disabled on java 8}@Test@EnabledIfSystemProperty(named = "os.arch", matches = ".*64.*")void testOnlyOn64bitSystem() {// TODO: this test is only run on 64 bit system}@Test@EnabledIfEnvironmentVariable(named = "DEBUG", matches = "true")void testOnlyOnDebugMode() {// TODO: this test is only run on DEBUG=true}
}

参数化测试

JUnit提供了一个@ParameterizedTest注解,用来进行参数化测试。参数化测试和普通测试稍微不同的地方在于,一个测试方法需要接收至少一个参数,然后,传入一组参数反复运行。

编写一个方法,该方法把字符串的第一个字母变为大写,后续字母变为小写。

在编写测试代码的时候,需要给出输入和预期输出,可以通过@MethodSource注解,它允许我们编写一个同名的静态方法来提供测试参数,编写一个静态方法testCapitalize返回了一组测试参数,每个参数都包含两个String,作为测试方法的两个参数传入。

还可以使用@CsvSource标记传入测试参数的方法,它的每一个字符串表示一行,一行包含的若干参数用 , 分隔。

如果测试数据很多,可以把测试数据提到一个独立的CSV文件中,标注上@CsvFileSource表示从CSV文件中读取数据。

由于JUnit只在classpath中查找指定的CSV文件,因此,test-capitalize.csv这个文件要放到src/main/resources目录下,内容格式如下图所示。

运行测试程序,测试结果如下图所示。

 StringUtils.java

public class StringUtils {public static String capitalize(String s) {if (s.length() == 0) {return s;}return Character.toUpperCase(s.charAt(0)) + s.substring(1).toLowerCase();}
}

StringUtilsTest.java

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;import static org.junit.jupiter.api.Assertions.*;public class StringUtilsTest {
//    @ParameterizedTest
//    @MethodSource
//    void testCapitalize(String input, String result) {
//        assertEquals(result, StringUtils.capitalize(input));
//    }
//
//    static List<Arguments> testCapitalize() {
//        return List.of( // arguments:
//                Arguments.of("abc", "Abc"), //
//                Arguments.of("APPLE", "Apple"), //
//                Arguments.of("gooD", "Good"));
//    }//    @ParameterizedTest
//    @CsvSource({"abc, Abc", "APPLE, Apple", "gooD, Good"})
//    void testCapitalize(String input, String result) {
//        assertEquals(result, StringUtils.capitalize(input));
//    }@ParameterizedTest@CsvFileSource(resources = {"test_capitalize.csv"})void testCapitalizeUsingCsvFile(String input, String result) {assertEquals(result, StringUtils.capitalize(input));}
}

相关文章:

Java IDEA JUnit 单元测试

JUnit是一个开源的 Java 单元测试框架&#xff0c;它使得组织和运行测试代码变得非常简单&#xff0c;利用JUnit可以轻松地编写和执行单元测试&#xff0c;并且可以清楚地看到哪些测试成功&#xff0c;哪些失败 JUnit 还提供了生成测试报告的功能&#xff0c;报告不仅包含测试…...

深入理解 c++ 函数模板

函数模板是C中的一种强大特性&#xff0c;它允许程序员编写一个可以处理多种数据类型的函数。通过使用模板&#xff0c;我们可以编写一次函数&#xff0c;然后在多种数据类型上使用它&#xff0c;这大大提高了代码的复用性。 1. 基本概念 函数模板是一种参数化类型的工具&…...

系列十二、Linux中安装Zookeeper

一、Linux中安装Zookeeper 1.1、下载安装包 官网&#xff1a;Index of /dist/zookeeper/zookeeper-3.4.11 我分享的链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/14Hugqxcgp89f2hqGWDwoBw?pwdyyds 提取码&#xff1a;yyds 1.2、上传至/opt目录 1.3、解…...

k8s之陈述式资源管理

1.kubectl命令 kubectl version 查看k8s的版本 kubectl api-resources 查看所有api的资源对象的名称 kubectl cluster-info 查看k8s的集群信息 kubectl get cs 查看master节点的状态 kubectl get pod 查看默认命名空间内的pod的信息 kubectl get ns 查看当前集群所有的命…...

7天玩转 Golang 标准库之 http/net

在构建web应用时&#xff0c;我们经常需要处理HTTP请求、做网页抓取或者搭建web服务器等任务&#xff0c;而Go语言在这方面为我们提供了强大的内置工具&#xff1a;net/http标准库&#xff0c;它为我们操作和处理HTTP协议提供了便利。 基础用法 一&#xff1a;处理HTTP请求 首…...

钡铼技术集IO数据采集可编程逻辑控制PLC无线4G环保物联网关

背景 数据采集传输对于环保企业进行分析和决策是十分重要的&#xff0c;而实时数据采集更能提升环保生产的执行力度&#xff0c;从而采取到更加及时高效的措施。因此实时数据采集RTU成为环保企业的必备产品之一。 产品介绍 在推进环保行业物联网升级过程中&#xff0c;环保RTU在…...

STM32CubeMX教程10 RTC 实时时钟 - 周期唤醒、闹钟A/B事件和备份寄存器

目录 1、准备材料 2、实验目标 3、实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.1 、时钟树配置 3.1.2、外设参数配置 3.1.3 、外设中断配置 3.2、生成代码 3.2.1、外设初始化函数调用流程 3.2.2、外设中断函数调用流程 3.2.3、添加其他必要代码 4、常用函数 …...

HarmonyOS4.0系统性深入开发08服务卡片架构

服务卡片概述 服务卡片&#xff08;以下简称“卡片”&#xff09;是一种界面展示形式&#xff0c;可以将应用的重要信息或操作前置到卡片&#xff0c;以达到服务直达、减少体验层级的目的。卡片常用于嵌入到其他应用&#xff08;当前卡片使用方只支持系统应用&#xff0c;如桌…...

002文章解读与程序——中国电机工程学报EI\CSCD\北大核心《计及源荷不确定性的综合能源生产单元运行调度与容量配置两阶段随机优化》已提供下载资源

&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;下载资源链接&#x1f4…...

Typora快捷键设置详细教程

文章目录 一、快捷键设置步骤二、设置快捷键简单案例参考资料 一、快捷键设置步骤 在typora软件中&#xff0c;快捷键的设置步骤主要为&#xff1a; 打开【文件】–>【偏好设置】&#xff0c;找到【通用】–>【打开高级设置】&#xff0c;找到 conf.user.json 文件。 然…...

《异常检测——从经典算法到深度学习》25 基于深度隔离林的异常检测算法

《异常检测——从经典算法到深度学习》 0 概论1 基于隔离森林的异常检测算法 2 基于LOF的异常检测算法3 基于One-Class SVM的异常检测算法4 基于高斯概率密度异常检测算法5 Opprentice——异常检测经典算法最终篇6 基于重构概率的 VAE 异常检测7 基于条件VAE异常检测8 Donut: …...

第7章 1 异常处理

bug的由来及分类 p81 字符串形式表示的数字之间也可以比较大小 import re ageinput(年龄&#xff1a;) if age>18:print(age)列表的append操作每次只能添加一个元素&#xff1a; lst[] lst.append(A) lst.append(B) # lst.append(A,B) 错误python中的异常处理机制 p82 t…...

昇腾910平台安装驱动、固件、CANN toolkit、pytorch

本文使用的昇腾910平台操作系统是openEuler&#xff0c;之前没了解过&#xff0c;不过暂时感觉用起来和centOS差不多。系统架构是ARM&#xff0c;安装包基本都是带aarch64字样&#xff0c;注意和x86_64区别开&#xff0c;别下错了。 安装依赖 cmake 通过yum安装的cmake版本较…...

【数据挖掘】模型融合

模型融合是指将多个不同的机器学习模型组合起来&#xff0c;通过综合多个模型的预测结果来得到更准确的预测结果。模型融合可以提高模型的鲁棒性&#xff0c;减小模型的方差&#xff0c;提高模型的泛化能力。 常见的模型融合方法包括平均法、投票法和堆叠法。 平均法(Averagin…...

DM、Oracle、GaussDB、Kingbase8(人大金仓数据库)和HIVE给列增加注释

DM数据库给列增加注释 1、创建表 CREATE TABLE test222 ( id int NOT NULL PRIMARY KEY, name varchar(1000) DEFAULT NULL, email varchar(1000) DEFAULT NULL, phone varchar(1000) DEFAULT NULL ) 2、给列添加注释 comment on column TEST222.NAME is 这是一个列注释; 例如…...

C语言实例_stdlib.h库函数功能及其用法详解

一、前言 C语言作为一种高效、灵活的编程语言&#xff0c;标准库的使用对于开发人员来说是不可或缺的。其中&#xff0c;stdlib.h是C语言中一个重要的标准库头文件&#xff0c;提供了许多常用的函数和工具&#xff0c;以便开发人员能够更加便捷地进行内存管理、字符串处理、随…...

Error in onLoad hook: “URIError: URI malformed“ found in…报错处理以及完善uniapp针对对象传参

使用uniapp传参的过程中遇到这么一个问题&#xff0c;当我们需要传整个对象作为参数时&#xff0c;我会先将这个对象先编码&#xff0c;然后再解码&#xff0c;从而获取到怎么参数&#xff0c;平常实操的时候也没有遇到过问题&#xff0c;但是今天测试的时候&#xff0c;刚好一…...

c语言-位操作符练习题

文章目录 前言一、n&(n-1)的运用场景(n为整数)二、&1 和 >>的应用场景总结 前言 本篇文章介绍利用c语言的位操作符解决一些练习题&#xff0c;目的是掌握各个位操作符的使用和应用场景。 表1.1为c语言中的位操作符 操作符含义&按位与|按位或^按位异或~按位…...

园林机械部件自动化三维测量检测形位公差-CASAIM自动化三维检测工作站

随着园林机械的广泛应用&#xff0c;对其机械部件的精确测量需求也日益增加。传统的测量方法不仅效率低下&#xff0c;而且精度难以保证&#xff0c;因此&#xff0c;自动化三维测量技术成为了解决这一问题的有效途径。本文将重点介绍CASAIM自动化三维检测工作站在园林机械部件…...

o2o生活通全开源尊享版+多城市切换+企业付款+交友IM+平台快报

搭建教程 1.把 pigo2ov282.sql 文件里面的网址 test.souho.net 全部批量替换为你的自己的 2.使用 phpmyadmin 导入 pigo2ov282.sql 到你的数据库&#xff08;直接访问/phpmyadmin 即可&#xff09; 3.修改数据库文件/conf/db.php 里的数据库连接信息&#xff08;请勿使用记事本…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...