Java单元测试

news/2024/12/18 15:36:55/文章来源:https://www.cnblogs.com/java-note/p/18615096

一、单元测试概述

  1. 定义
    • 单元测试是对软件中的最小可测试单元进行检查和验证。在Java中,最小可测试单元通常是一个方法。它的目的是隔离各个部分的代码,确保它们能够正确地独立运行,便于早期发现代码中的错误。
  2. 重要性
    • 提高代码质量:能够快速定位代码中的问题,比如逻辑错误、边界条件处理不当等。例如,在一个简单的数学计算方法add(int a, int b)中,单元测试可以验证各种输入情况下(如正数、负数、零)的计算结果是否正确。
    • 便于代码重构:当对代码进行重构时,单元测试可以帮助确保功能没有被破坏。比如,将一个复杂的算法从一种实现方式改为另一种更高效的实现方式,只要单元测试通过,就可以很大程度上保证功能的完整性。
    • 促进团队协作:不同的开发人员可以根据单元测试来理解代码的功能和预期行为,特别是在代码交接或者多人协作开发的项目中。

二、常用的单元测试框架 - JUnit

  1. 添加依赖

    • 如果使用Maven构建项目,需要在pom.xml文件中添加JUnit依赖。例如,对于JUnit 5,添加以下依赖:
    <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.8.2</version><scope>test</scope>
    </dependency>
    
    • 如果是Gradle构建的项目,在build.gradle文件中添加类似如下内容:
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
    
  2. 编写简单的测试用例

    • 假设我们有一个简单的Java类Calculator,其中有一个加法方法add
    class Calculator {public int add(int a, int b) {return a + b;}
    }
    
    • 我们可以编写JUnit测试用例来测试这个方法:
    import org.junit.jupiter.api.Test;
    import static org.junit.jupiter.api.Assertions.*;class CalculatorTest {@Testpublic void testAdd() {Calculator calculator = new Calculator();int result = calculator.add(2, 3);assertEquals(5, result);}
    }
    
    • 在这个测试用例中,@Test注解标记了testAdd方法是一个测试方法。assertEquals是JUnit提供的断言方法,用于验证实际结果(result)是否等于预期结果(5)。
  3. 测试方法的执行顺序和生命周期(JUnit 5)

    • 方法执行顺序:默认情况下,JUnit 5测试方法的执行顺序是不确定的。但是可以使用@TestMethodOrder注解来指定顺序。例如,使用MethodOrderer.OrderAnnotation可以按照方法上的@Order注解指定的顺序执行:
    import org.junit.jupiter.api.MethodOrderer;
    import org.junit.jupiter.api.Order;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.TestMethodOrder;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    class MyTestClass {@Test@Order(1)public void firstTest() {//...}@Test@Order(2)public void secondTest() {//...}
    }
    
    • 生命周期:JUnit 5引入了@BeforeEach@AfterEach@BeforeAll@AfterAll注解来管理测试方法的生命周期。
    • @BeforeEach:在每个测试方法执行之前执行。例如,可以用于初始化测试对象或设置测试环境。
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;class MyTestClass {private MyObject myObject;@BeforeEachpublic void setup() {myObject = new MyObject();}@Testpublic void testMethod() {// 使用myObject进行测试}
    }
    
    • @AfterEach:在每个测试方法执行之后执行,可用于清理资源等操作。
    • @BeforeAll:在所有测试方法执行之前执行一次,通常用于初始化一些共享的资源,并且这个方法必须是静态的。
    • @AfterAll:在所有测试方法执行之后执行一次,也必须是静态的,用于释放共享资源。

三、单元测试中的断言

  1. 基本断言方法(JUnit)
    • assertEquals:用于比较两个值是否相等。它有多种重载形式,可以比较基本数据类型、对象等。例如:
    assertEquals(10, myMethodReturningIntValue());
    assertEquals("expectedString", myMethodReturningStringValue());
    
    • assertTrueassertFalse:用于验证一个布尔表达式的结果。例如:
    assertTrue(myBooleanMethod());
    assertFalse(myFalseBooleanMethod());
    
    • assertNullassertNotNull:用于检查对象是否为null。例如:
    assertNull(myMethodReturningNull());
    assertNotNull(myObject);
    
  2. 断言异常抛出
    • 在单元测试中,有时需要验证方法是否正确地抛出了异常。例如,对于一个可能抛出IllegalArgumentException的方法divide
    import org.junit.jupiter.api.Test;
    import static org.junit.jupiter.api.Assertions.*;class MyMathTest {@Testpublic void testDivideByZero() {MyMath math = new MyMath();assertThrows(IllegalArgumentException.class, () -> {math.divide(5, 0);});}
    }
    
    • 这里assertThrows方法用于验证代码块(lambda表达式部分)是否抛出了指定类型(IllegalArgumentException)的异常。

四、测试覆盖率

  1. 定义和重要性
    • 测试覆盖率是指测试用例覆盖了被测试代码的程度。它是衡量单元测试质量的一个重要指标。高测试覆盖率意味着更多的代码被测试到,减少了未被发现的错误的可能性。
  2. 工具介绍 - JaCoCo(Java Code Coverage)
    • 添加依赖:在Maven项目中,添加如下依赖:
    <dependency><groupId>org.jacoco</groupId><artifactId>jacoco - maven - plugin</artifactId><version>0.8.8</version>
    </dependency>
    
    • 配置和使用:在pom.xml文件的build部分配置插件:
    <build><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco - maven - plugin</artifactId><version>0.8.8</version><executions><execution><goals><goal>prepare - agent</goal></goals></execution><execution><id>report</id><phase>test</phase><goals><goal>report</goal></goals></execution></executions></plugin></plugins>
    </build>
    
    • 运行mvn test后,会在target/site/jacoco目录下生成测试覆盖率报告,可以通过浏览器打开index.html文件查看详细的覆盖率信息,包括语句覆盖、分支覆盖等情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/854844.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

冬季游戏协作挑战,6 款办公软件能否成为团队的坚实后盾?

在游戏行业的节日盛宴中,每一个新游戏的上线或重大更新都是一场与时间赛跑的挑战,需要开发团队、测试团队和运营团队如同精密齿轮般紧密协作。而可视化团队协作办公软件则成为了推动这一复杂机器高效运转的润滑剂。本文将站在全 J 人游戏公司的视角,深入剖析 6 款此类办公软…

打架监测报警摄像机

打架监测报警摄像机是一种专门用于监测和预警打架事件的安全设备。这种摄像机一般配备高清摄像头和智能分析算法,可以实时监测监控区域内的人员活动,并在检测到打架行为时立即触发警报系统。打架监测报警摄像机是现代安防领域中一种重要的监控设备,主要用于预防和打击暴力事…

火情监测报警摄像机

火情监测报警摄像机是一种专门用于监测火灾并发出警报的安全设备,通常安装在建筑物、工厂、仓库等易发生火灾的地方,用于实时监测火情并及时通知相关人员。火情监测报警摄像机是一种结合了视频监控和火灾报警功能的智能安全设备,旨在实时监测和检测火情,提前发现和预警火灾…

241218_GIS要素内点要素提取平均值

当一个面要素中有多个点要素时,需要提取点要素的平均值并赋值到面要素中方法使用空间连接 空间连接存在一个功能右键字段-属性2.选择平均值本文来自博客园,作者:我在乎的,转载请注明原文链接:https://www.cnblogs.com/wzh/p/18615058

流动商贩乱摆摊占道智能监控系统

流动商贩乱摆摊占道智能监控系统核心在于深度学习算法的运用,流动商贩乱摆摊占道智能监控系统对高清摄像头捕捉到的图像进行深度分析,识别出违规撑伞、出店经营、车辆占道违停以及违规广告牌等行为。这些行为往往是城市管理中的顽疾,传统方法难以有效监管,而智能监控系统则…

鸿蒙开发之无须申请权限访问相册图片

访问相册图片介绍 在应用开发中,很多场景需要我们需要访问相册中的图片。例如:上传头像、上传银行卡、身份证资料、扫描文件功能、美颜功能等 所以访问相册里的图片成为我们必须要学习和掌握的内容。那如何访问相册图片呢? 在HarmonyOS中,鉴于对用户隐私的高度保护,要方便…

鸿蒙开发之不申请权限写入图片到相册

写入图片到相册介绍 在上一篇中,猫林老师给大家分享了如何在不申请权限的情况下读取相册内容。这一篇教大家如何写入图片到相册。 这在应用开发中,也是一个很常见的场景,比如我们要做一个文件扫描的功能。那是不是得把扫描的结果保存到图库呢?再比如我们做一个美颜的功能,…

清明上河图密码 26 集 电视剧 All In One

清明上河图密码 26 集 电视剧 All In One 《清明上河图密码》2024年播出的中国大陆古装悬疑电视剧,改编自中国大陆作家冶文彪创作的同名小说,由电影《男欢女爱》的导演杨帆与《深渊宝藏》的导演熊琛联合执导,张颂文、白百何领衔主演,周一围、侯岩松特别主演,张耀、夏梦、林…

python执行subprocess.run报错

问题 执行 subprocess.run(command, check=True) 时报错 File "C:\Users\xxx\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1420, in _execute_childhp, ht, pid, tid = _winapi.CreateProcess(executable, args,FileNotFoundError:[WinError 2…

二:使用正点原子的直流无刷驱动板自写FOC控制永磁同步(PMSM)电机(位置闭环)

在上一篇博客中配置了UVW三相PWM的定时器,在此基础上增加配置ABZ编码器定时器启用一个定时器中断,用于PID处理 代码如下// 常量定义 #define PI 3.14159265359f #define PWM_RESOLUTION 5250.0f // PWM分辨率 #define CIRCLE_RESOLUTION 1000 // 圆周分辨率 #define MOTOR_…

易基因:游离细胞DNA(cfDNA)检测整体研究方案

01.技术简述 细胞游离DNA(cell-free DNA,cfDNA)是指在生物体的体液中(如血浆、尿液、脑脊液等)自由存在的、非细胞内的DNA片段。这些DNA片段通常来源于细胞凋亡(程序性死亡)或坏死(细胞损伤或死亡后释放),可以被释放到循环系统中,并在体液中被检测到。cfDNA研究和应…

域名历史是什么?怎么进行域名历史查询?

域名是互联网上用来识别和访问网站的一个易于记忆的地址。它将IP地址转换成人类可读的格式,例如 www.example.com。域名是互联网的基础,每个网站都需要一个独特的域名以便用户能够访问。 什么是域名历史? 域名历史记录了一个域名自注册以来的所有变更,包括所有权、DNS设置、…