浅谈单元测试和JUnit4使用

什么是单元测试

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

为什么要写单元测试

以下列举了一些我为什么使用单元测试的好处:

  • 允许代码做出改变,因为你了解单元测试会在你的预期之中。
  • 单元测试可以有效地降低程序出现BUG的机率;
  • 帮助你更深入地理解代码–因为在写单元测试的时候,你需要明确程序所有的执行流程及对应的执行结果等;
  • 允许在任何时候代码重构,而不必担心破坏现有的代码。这使得我们编写程序更灵活;确保你的代码的健壮性,因为所有的测试都是通过了的。
  • 文档记录。单元测试就是一种无价的文档,它是展示函数或类如何使用的最佳文档,这份文档是可编译、可运行的、并且它保持最新,永远与代码同步。
  • 具有回归性。自动化的单元测试避免了代码出现回归,编写完成之后,可以随时随地地快速运行测试,而不是将代码部署到设备之后,然后再手动地覆盖各种执行路径,这样的行为效率低下,浪费时间。

什么时候写单元测试

编写单元测试的时机通常有三种情况。首先,在具体实现代码之前进行,这是测试驱动开发(TDD)所倡导的方法。其次,与具体实现代码同步进行,即先编写少量功能代码,然后紧接着编写单元测试(重复这两个过程,直到完成功能代码开发)。实际上,这种方案与第一种非常接近,基本上功能代码开发完成后,单元测试也差不多完成了。最后,第三种情况是在编写完功能代码后再编写单元测试。根据我的经验,事后编写的单元测试的粒度通常较粗。对于同样的功能代码,采用前两种方案的结果可能是用10个较小的单元测试来覆盖,每个单元测试相对简单易懂,可读性和可维护性都较好(重构时单测的改动较小);而采用第三种方案编写的单元测试,往往是用1个较大的单元测试来覆盖,这个单元测试的逻辑就比较复杂,因为它需要测试的东西很多,可读性和可维护性相对较差。
建议:我个人比较推荐将单元测试与具体实现代码同步进行的方案。只有对需求有一定的理解后,才能知道什么是代码的正确性,才能编写出有效的单元测试来验证正确性。能够编写一些功能代码说明对需求已经有一定理解了。

单元测试要写多细

单元测试不是越多越好,而是越有效越好!进一步解读就是哪些代码需要有单元测试覆盖:

  • 逻辑复杂的
  • 容易出错的
  • 不易理解的,即使是自己过段时间也会遗忘的,看不懂自己的代码,单元测试代码有助于理解代码的功能和需求
  • 公共代码。比如自定义的所有http请求都会经过的拦截器;工具类等。
  • 核心业务代码。一个产品里最核心最有业务价值的代码应该要有较高的单元测试覆盖率。

JUnit4

HelloWorld 例子
我们已一个简单的例子来快速展示 JUnit4 的基本用法.
首先新建一个名为 JUniTest 的 Maven 工程, 然后添加依赖:

<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
</dependencies>

编写测试代码:

import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestJunit {@Testpublic void testingCrunchifyAddition() {assertEquals("Here is test for Addition Result: ", 30, addition(27, 3));}@Testpublic void testingHelloWorld() {assertEquals("Here is test for Hello World String: ", "Hello + World", helloWorld());}public int addition(int x, int y) {return x + y;}public String helloWorld() {String helloWorld = "Hello +" + " World";return helloWorld;}
}

使用测试用例:

public class App {public static void main(String[] args) {Result result = JUnitCore.runClasses(TestJunit.class);for (Failure failure : result.getFailures()) {System.out.println(failure.toString());}if (result.wasSuccessful()) {System.out.println("Both Tests finished successfully...");}}
}public class TestJunit {@Testpublic void testingCrunchifyAddition() {assertEquals("Here is test for Addition Result: ", 30, addition(27, 3));}...
}

JUnit4 注解

  • @Test (expected = Exception.class) 表示预期会抛出Exception.class 的异常

  • @Ignore 含义是“某些方法尚未完成,暂不参与此次测试”。这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore注解删去,就可以进行正常的测试。

  • @Test(timeout=100) 表示预期方法执行不会超过 100 毫秒,控制死循环

  • @Before 表示该方法在每一个测试方法之前运行,可以使用该方法进行初始化之类的操作

  • @After 表示该方法在每一个测试方法之后运行,可以使用该方法进行释放资源,回收内存之类的操

  • @BeforeClass 表示该方法只执行一次,并且在所有方法之前执行。一般可以使用该方法进行数据库连接操作,注意该注解运用在静态方法。

  • @AfterClass 表示该方法只执行一次,并且在所有方法之后执行。一般可以使用该方法进行数据库连接关闭操作,注意该注解运用在静态方法。

JUnit4测试用例的完整的生命周期

要经历如下几个阶段:

  1. 类级初始化资源处理
  2. 方法级初始化资源处理
  3. 执行测试用例中的方法
  4. 方法级销毁资源处理
  5. 类级销毁资源处理

其中, 类级初始化和销毁资源处理在每一个测试用例类这仅仅执行一次, 方法级初始化, 销毁资源处理方法在执行测试用例这的每个测试方法中都会被执行一次.

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

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

相关文章

【计算机视觉】图像处理算法(其他篇)

来源&#xff1a;《OpenCV3编程入门》&#xff0c;怀念毛星云大佬&#x1f56f;️ 说明&#xff1a;本系列重点关注各种图像处理算法的原理、作用和对比 漫水填充 漫水填充法是一种用特定的颜色填充连通区域&#xff0c;通过设置可连通像素的上下限以及连通方式来达到不同的填…

为什么传奇服务器经常被攻击?

传奇服务器攻击类型大致分三种&#xff0c;一、CC假人登录攻击&#xff0c;这种攻击类型是不断的模仿真的传奇&#xff0c;玩家在登录你的游戏&#xff0c;但一直不登录进入&#xff0c;让你的登录网关饱满&#xff0c;这个是很常见的攻击类型&#xff0c;经常到了广告时间&…

MyBatisPlus理解

MyBatisPlus是mybatis的增强&#xff0c;mybatis是数据库持久化的框架&#xff0c;但mybatisplus并不是替代mybatis&#xff0c;而是相辅相成的关系 MyBatisPlus不会对以前使用mybatis开发的项目进行影响&#xff0c;引入后仍然正常运行。 使用方法&#xff1a; 1.在引入了对…

使用Spring的AOP

使用Spring的AOP 一、AOP 的常用注解1.切面类Aspect2.Pointcut3.前置通知Before4.后置通知AfterReturning5.环绕通知Around6.异常通知AfterThrowing7.最终通知After8.切面顺序Order9.启用自动代理EnableAspectJAutoProxy 二、AOP注解方式开发三、AOP 全注解开发四、基于XML配置…

5G网络助力智慧文旅发展:实现旅游资源的优化配置与高效利用

目录 一、5G网络在智慧文旅中的关键作用 1、高速率传输提升数据处理能力 2、低时延助力实时决策与调度 3、大连接实现全面覆盖与精细化管理 二、5G网络助力实现旅游资源的优化配置 1、精准匹配游客需求与旅游资源 2、促进旅游资源的跨区域合作与共享 三、5G网络助力实现…

【Python】科研代码学习:七 TrainingArguments,Trainer

【Python】科研代码学习&#xff1a;七 TrainingArguments&#xff0c;Trainer TrainingArguments重要的方法 Trainer重要的方法使用 Trainer 的简单例子 TrainingArguments HF官网API&#xff1a;Training 众所周知&#xff0c;推理是一个大头&#xff0c;训练是另一个大头 之…

XSS-Labs靶场“11-13、15-16”关通关教程

君衍. 一、第十一关 referer参数注入二、第十二关 user-agent参数注入三、第十三关 cookie参数绕过四、第十五关 ng-include文件包含五、第十六关 回车代替空格 点击跳转&#xff1a; XSS-Labs靶场“1-5”关通关教程 XSS-Labs靶场“6-10”关通关教程 一、第十一关 referer参数…

[uni-app ] createAnimation锚点旋转 及 二次失效问题处理

记录一下: 锚点定位到左下角, 旋转动画 必须沿Z轴,转动 但是,此时会出现 后续动画在微信小程序失效问题 解决: 清空 this.animationData

HuggingFace Hub系列:推动NLP前进的协作平台

在当今快速发展的机器学习(ML)领域&#xff0c;没有任何一个公司&#xff0c;包括科技巨头&#xff0c;能够独立“解决AI”。这是一个需要通过共享知识和资源在社区中协作来实现的目标。正是基于这个信念&#xff0c;Hugging Face Hub应运而生&#xff0c;它是一个集成了超过12…

201912青少年软件编程(Scratch)等级考试试卷(一级)

201912 青少年软件编程&#xff08;Scratch&#xff09;等级考试试卷&#xff08;一级&#xff09; 第1题&#xff1a;【 单选题】 关于造型和背景&#xff0c;下面说法不正确的是&#xff1f; A:造型编号从1开始 B:有四个背景&#xff0c;删除第二个背景&#xff0c;背景编…

11_Http

文章目录 HttpHttp协议网络模型Http协议的工作流程Http请求报文请求行请求方法请求资源协议版本 请求头空行请求体抓包软件&#xff1a;Fiddler Http响应报文响应行状态码 响应头响应体 请求完整的处理流程 Https 整体流程图&#xff1a; 前端&#xff1a;负责获取数据&#xf…

雷赛控制卡获取轴当前位置的值不正确问题处理

现像 从雷赛控制卡中获取当前轴位置值时发现轴在向零点的右边走时显示的值是负数。正常来就一般是要反馈正数的。一般轴零点右边是正方向&#xff0c;限位是正限位&#xff0c;反馈的位置也应该是正数。 如果雷赛软件中的【单轴参数】中的基本设置中的【脉冲模式】设置的是对的…

【C语言基础】:深入理解指针(终篇)

文章目录 深入理解指针一、函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 typedef关键字 二、函数指针数组三、转移表四、回调函数4.1 什么是回调函数4.2 qsort使用举例4.2.1 使用qsort函数排序整形数据4.2.2 使用qsort排序结构数据4.2.3 qsort函数的模拟实现 …

elasticsearch 深度分页查询 Search_after(图文教程)

Search_after使用 一. 简介二. 不带PIT的search_after查询2.1 构造数据2.2 search_after分页查询2.2 问题 三. 带PIT的search_after查询3.1 构建第一次查询条件3.2 进行下一页查询3.3 删除PIT 四.参考文章 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注…

【调试记录】vscode远程连接问题汇总

1. kex_exchange_identification kex_exchange_identification: read: Connection reset by xxx.xx.xx.x 一直连不上实验室的服务器&#xff0c;用PUTTY和Mobaxterm也不行&#xff08;报错&#xff1a;Remote side unexpectedly closed network connection&#xff09;。已知…

傅里叶变换pytorch使用

参考视频&#xff1a;1 傅里叶变换原理_哔哩哔哩_bilibili 傅里叶变换是干嘛的&#xff1a; 傅里叶得到低频、高频信息&#xff0c;针对低频、高频处理能够实现不同的目的。 傅里叶过程是可逆的&#xff0c;图像经过傅里叶变换、逆傅里叶变换后&#xff0c;能够恢复到原始图像…

【管理干部竞聘上岗】某星级酒店中层干部竞聘上岗管理咨询项目纪实

在这次项目合作中&#xff0c;我们的目的主要是设计一次公开、透明的竞聘活动&#xff0c;通过科学、公正的方法选拔出公司管理级岗位的最佳候选人。基于华恒智信的专业性&#xff0c;我们再次选择与其合作开展项目。在项目合作中&#xff0c;专家团队为我们进行了专业性的培训…

AIGC实战——GPT(Generative Pre-trained Transformer)

AIGC实战——GPT 0. 前言1. GPT 简介2. 葡萄酒评论数据集3. 注意力机制3.1 查询、键和值3.2 多头注意力3.3 因果掩码 4. Transformer4.1 Transformer 块4.2 位置编码 5. 训练GPT6. GPT 分析6.1 生成文本6.2 注意力分数 小结系列链接 0. 前言 注意力机制能够用于构建先进的文本…

【网络原理】TCP 协议中比较重要的一些特性(一)

目录 1、TCP 协议 2、确认应答 2.1、确认序号 3、超时重传 4、连接管理 4.1、建立连接&#xff08;三次握手&#xff09; 4.2、断开连接&#xff08;四次挥手&#xff09; 1、TCP 协议 TCP 是工作中最常用到的协议&#xff0c;也是面试中最常考的协议&#xff0c;具有面…

软考高级:单元测试、集成测试、确认测试(内部确认测试、Alpha 测试、Beta测试、验收测试)概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…