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

Java 单元测试最佳实践:如何充分利用测试自动化

单元测试是众所周知的做法,但还有很大的改进空间!在这篇文章中,我们讨论最有效的单元测试最佳实践,包括在此过程中最大化自动化工具的方法。我们还将讨论代码覆盖率、模拟依赖关系和整体测试策略。

什么是单元测试?
单元测试是测试应用程序的各个单元或组件的做法,以验证每个单元是否正常工作。一般来说,一个单元应该是应用程序的一小部分——在 Java 中,它通常是一个类。请注意,我在这里并没有严格定义“单元”,而是由开发人员决定每个测试的测试代码的范围。

人们有时会将术语“单元测试”与“集成测试”或“端到端测试”进行对比。区别在于,通常,单元测试是为了验证单个可测试单元的行为,而集成测试是验证多个组件一起或整个应用程序的行为。正如我所说,“单元”的构成并没有严格定义,每个测试的范围由您决定。

为什么要进行单元测试?
单元测试是一种经过验证的确保软件质量的技术,具有很多好处。以下是进行单元测试的几个重要原因:

单元测试验证您的每个软件不仅现在可以正常工作,而且在未来也可以继续工作,为未来的开发提供坚实的基础。
单元测试可以在生产过程的早期阶段识别缺陷,从而降低在开发周期后期修复这些缺陷的成本。
经过单元测试的代码通常重构起来更安全,因为可以快速重新运行测试以验证行为没有改变。
编写单元测试迫使开发人员考虑生产代码的设计如何,以使其适合单元测试,并使开发人员从不同的角度看待他们的代码,鼓励他们在实现中考虑极端情况和错误情况。
在代码审查过程中包括单元测试可以揭示修改后的或新的代码应该如何工作。另外,审阅者可以确认测试是否良好。
不幸的是,很多时候,开发人员要么根本不编写单元测试,要么不编写足够的测试,要么不维护它们。我理解——单元测试有时编写起来很棘手,或者维护起来很耗时。有时需要满足最后期限,感觉编写测试会让我们错过那个最后期限。但是,没有编写足够的单元测试或没有编写良好的单元测试是一个很容易陷入的危险陷阱。

因此,请考虑我以下关于如何编写干净、可维护、自动化测试的最佳实践建议,这些测试可以让您以最少的时间和精力享受单元测试的所有好处。

单元测试最佳实践
让我们看一下构建、运行和维护单元测试的一些最佳实践,以获得最佳结果。

单元测试应该值得信赖
如果代码被破坏并且仅当代码被破坏时测试必定失败。如果不是,我们就不能相信测试结果告诉我们的内容。

单元测试应该是可维护和可读的
当生产代码发生变化时,测试通常需要更新,也可能需要调试。因此,测试必须易于阅读和理解,不仅对于编写测试的人来说,而且对于其他开发人员来说也是如此。始终为了清​​晰和可读性而组织和命名您的测试。

单元测试应该验证单个用例
好的测试只能验证一件事,而且只能验证一件事,这意味着它们通常会验证单个用例。遵循此最佳实践的测试更简单且更易于理解,这有利于可维护性和调试。验证不止一件事的测试很容易变得复杂且维护起来耗时。不要让这种事发生。

另一个最佳实践是使用最少数量的断言。有些人建议每个测试只使用一个断言(这可能有点过于严格);这个想法是专注于仅验证您正在测试的用例所需的内容。

单元测试应该隔离
测试应该可以在任何机器上以任何顺序运行,而不会相互影响。如果可能,测试不应依赖于环境因素或全局/外部状态。具有这些依赖项的测试更难运行并且通常不稳定,这使得它们更难调试和修复,并且最终花费的时间比节省的时间更多(请参阅上面的trustworthy)。

几年前,Martin Fowler撰写了有关 “孤独”与“社交”代码的文章,以描述应用程序代码中的依赖项使用情况,以及如何相应地设计测试。在他的文章中,“独立”代码不依赖于其他单元(它更加独立),而“社交”代码确实与其他组件交互。如果应用程序代码是孤独的,那么测试很简单,但对于被测试的社交代码,您可以构建“孤独”或“社交”测试。“社交测试”将依赖于真实的依赖关系来验证行为,而“单独测试”则将被测代码与依赖关系隔离开来。您可以使用模拟来隔离被测代码,并为“社交”代码构建“单独”测试。我们将在下面看看如何做到这一点。

一般来说,使用模拟来处理依赖关系使我们作为测试人员的生活更轻松,因为我们可以为社交代码生成“单独的测试”。对复杂代码的社交测试可能需要大量设置,并且可能违反隔离和可重复的原则。但由于模拟是在测试中创建和配置的,因此它是独立的,我们可以更好地控制依赖项的行为。另外,我们可以测试更多代码路径。例如,我可以返回自定义值或从模拟中抛出异常,以覆盖边界或错误条件。

单元测试应该自动化
确保测试在自动化过程中运行。这可以是每天,也可以是每小时,也可以是在持续集成或交付过程中。团队中的每个人都需要能够访问和审查这些报告。作为一个团队,讨论您关心哪些指标:代码覆盖率、修改后的代码覆盖率、正在运行的测试数量、性能等。

通过查看这些数字可以学到很多东西,这些数字的大幅变化通常表明可以立即解决回归问题。
单元测试应验证所有细节、极端情况和边界条件等。应更加谨慎地使用组件、集成、UI 和功能测试,以验证 API 或应用程序作为一个整体的行为。手动测试应该占整个金字塔结构的最小百分比,但对于发布验收和探索性测试仍然有用。该模型为组织提供了高水平的自动化和测试覆盖率,以便他们可以扩大测试工作并将与构建、运行和维护测试相关的成本保持在最低水平。

单元测试应在有组织的测试实践中执行
为了推动各级测试的成功,并使单元测试过程可扩展且可持续,您将需要一些额外的实践。首先,这意味着在编写应用程序代码时编写单元测试。一些组织在应用程序代码之前编写测试(测试驱动或行为驱动编程)。重要的是测试与应用程序代码齐头并进。测试和应用程序代码甚至应该在代码审查过程中一起审查。评论可以帮助您理解正在编写的代码(因为它们可以看到预期的行为)并改进测试!

相关文章:

Java 单元测试最佳实践:如何充分利用测试自动化

单元测试是众所周知的做法,但还有很大的改进空间!在这篇文章中,我们讨论最有效的单元测试最佳实践,包括在此过程中最大化自动化工具的方法。我们还将讨论代码覆盖率、模拟依赖关系和整体测试策略。 什么是单元测试? 单…...

windows系统用于 SDN 的软件负载均衡器 (SLB)

适用于:Azure Stack HCI 版本 22H2 和 21H2;Windows Server 2022、Windows Server 2019、Windows Server 2016 软件负载均衡器包括哪些内容? 软件负载均衡器提供以下功能: 适用于北/南和东/西 TCP/UDP 流量的第 4 层 (L4) 负载均…...

漏洞复现--IP-guard flexpaper RCE

免责声明: 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…...

Electron-vue出现GET http://localhost:9080/__webpack_hmr net::ERR_ABORTED解决方案

GET http://localhost:9080/__webpack_hmr net::ERR_ABORTED解决方案 使用版本解决方案解决总结 使用版本 以下是我解决此问题时使用的electron和vue等的一些版本信息 【附】经过测试 electron 的版本为 13.1.4 时也能解决 解决方案 将项目下的 .electron-vue/dev-runner.js…...

Linux---(六)自动化构建工具 make/Makefile

文章目录 一、make/Makefile二、快速查看(1)建立Makefile文件(2)编辑Makefile文件(3)解释(4)效果展示 三、背后的基本知识、原理(1)如何清理对应的临时文件呢…...

谷歌:编写干净的代码以减少认知负荷

您是否曾经阅读过代码却发现很难理解?您可能正在经历认知负荷! 认知负荷是指完成一项任务所需的脑力劳动量。阅读代码时,您必须记住变量值、条件逻辑、循环索引、数据结构状态和接口契约等信息。随着代码变得更加复杂,认知负荷也…...

微信小程序display常用属性和子元素排列方式介绍

wxss中display常用显示属性与css一致,介绍如下: 针对元素本身显示的属性: displayblock,元素显示换行displayinline,元素显示换行,但不可设置固定的宽度和高度,也不可设置上下方向的margin和p…...

设计模式—结构型模式之代理模式

设计模式—结构型模式之代理模式 代理模式(Proxy Pattern) ,给某一个对象提供一个代理,并由代理对象控制对原对象的引用,对象结构型模式。 静态代理 比如我们有一个直播平台,提供了直播功能,但是如果不进行美颜,可能就比较冷清…...

C# PDF转HTML字符串

需要nuget安装Aspose.PDF插件,本文使用23.10.0版本 一、获取PDF文件,保存到某个路径;再读取返回字符串。 //html文件保存路径 string filePath dirPath "xxx.html"; if (!File.Exists(filePath)) {//获取pdf文件流Byte[] pdfBy…...

el-table解决数据过少小于高度有留白的问题

问题:给el-table设置个高度,高度为500px,之后就添加如下4条数据,那么底部就没数据,直接就空白了,本文章就是为了解决这个问题,如果底部留白那么就添加几条空数据就行了.如果数据已达到高度了那么就不会留白了 1.效果 这个空列可以根据高度来决定添加几个空格子去铺满列表&…...

vue实现无感刷新token

vue实现无感刷新token 1、前言2、实现思路2.1 方法一2.2 方法二2.3 方法三 3、可能遇到的问题3.1 问题一:如何防止多次刷新token3.2 问题二:同时发起两个或者两个以上的请求时,其他接口怎么解决 1、前言 最近在做vue3管理系统项目的时候&…...

竞赛选题 深度学习的动物识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…...

Python高级语法----Python C扩展与性能优化

文章目录 1. 编写Python C扩展模块示例代码编译和运行运行结果2. 利用Cython优化性能示例代码编译和运行运行结果3. Python性能分析工具示例代码分析结果1. 编写Python C扩展模块 Python C扩展模块允许你将C语言代码集成到Python程序中,以提高性能。这对于计算密集型任务特别…...

行业洞察:分布式云如何助力媒体与娱乐业实现创新与增长?

过去数年,流媒体经历了蓬勃的发展过程,观众可以根据喜好收看自己所喜爱的节目内容,并希望在全球范围内访问内容。 繁荣的市场让媒体和娱乐行业的 IT 领导者们竞相发力,用更短的时间去创造互动且令人难忘的内容体验,力求…...

【多线程 - 05、后台线程】

后台线程 后台线程,它是在后台运行的,它的任务是为其他线程提供服务,这种线程被称为“后台线程(Daemon Thread)”,又称为“守护线程”或“精灵线程”。JVM的垃圾回收线程就是典型的后台线程。 后台线程的特…...

C语言之文件操作(剩余部分)

上篇博客字数到极限了,给大家把内容补充在这一篇,我们还剩下文件读取结束的判定和文件缓冲区的内容没有介绍,让我们开始下面的学习吧! 目录 1.文件读取结束的判定 1.1feof函数 1.2ferror函数 代码示例 2.文件缓冲区 2.1fflu…...

【PC】开发者日志:竞技比赛验证系统强化

各位玩家大家好!欢迎收看本期开发者日志。 在11月1日发布的第26赛季第2轮更新公告中,我们提到了有关强化比赛验证系统的内容。想必各位玩家一定会对我们加强验证系统的背景和意图感到好奇,为此我们想通过今天这篇反作弊开发者日志来向大家更详…...

c++用map,创建类似于python中的字典

1.创建 #include <map> #include <string> #include <iostream>using namespace std; int main() {/*using std::map;using std::string;using std::cout;*/map<string, string> myMap1 {{"Name", "ClearLove"},{"Gender&q…...

VuePress介绍及使用指南

VuePress是一个基于Vue.js的静态网站生成工具&#xff0c;它专注于以Markdown为中心的项目文档。VuePress具有简单易用的特性&#xff0c;同时提供了强大的自定义和扩展性。在本文中&#xff0c;我们将介绍VuePress的基本概念&#xff0c;并提供一个简单的使用指南。 什么是Vue…...

Spring-Security前后端分离权限认证

前后端分离 一般来说&#xff0c;我们用SpringSecurity默认的话是前后端整在一起的&#xff0c;比如thymeleaf或者Freemarker&#xff0c;SpringSecurity还自带login登录页,还让你配置登出页,错误页。 但是现在前后端分离才是正道&#xff0c;前后端分离的话&#xff0c;那就…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...