为什么需要写Java单元测试总结

目录

前言

一、为什么写单元测试

写单测好处

1、提升效率

2、场景覆盖全

单测怎么写

1、集成测试

2、单元测试

Mock框架

1、Mockito单元测试

2、Mockito 中文文档地址

二、强制要求

1.好的单元测试必须遵守AIR原则。

2.单元测试应该是全自动执行的,并且非交互式的。

3.保持单元测试的独立性。

4.单元测试是可以重复执行的,不能受到外界环境的影响。

被测系统

5.对于单元测试,要保证测试粒度足够小。

6.核心业务、核心应用、核心模块的增量代码,确保单元测试通过。

7.单元测试代码目录

三、推荐要求

1.单元测试的基本目标

2.编写单元测试代码时遵守BCDE原则,以保证被测试模块的交付质量。

3.对于数据库的相关查询、更新和删除等操作

4.和数据库相关的单元测试

5.对于不可测的代码

6.在设计评审阶段

7.单元测试作为一种质量保障手段

四、参考要求

1.为了更方便地进行单元测试,业务代码应该避免一下情况

2.不要对单元测试存在如下误解

五、单元测试与集成测试的区别

1.测试对象不同

2.测试方法不同

3.测试时间不同

4.测试内容不同

六、为什么要使用Mock做测试

1.Mock可以用来解除外部服务依赖,从而保证了测试用例的独立性。

2.Mock可以减少全链路测试数据准备,从而提高了编写测试用例的速度。

3.Mock可以模拟一些非正常的流程,从而保证了测试用例的代码覆盖率。

4.Mock可以不用加载项目环境配置,从而保证了测试用例的执行速度。


前言

为了保证代码质量,在写完代码后,写单测是很有必要的。当然,在大部分情况下,我们可能不会写单测,而是直接把应用部署起来,直接自测,然后再联调。估计很大一部分人,都是用这种方式开发。当然,我之前也是按这个方式来开发,单测覆盖率纯粹是为了满足公司的指标要求,大部分流于形式。

一、为什么写单元测试

说到单元测试,就不得不提起另一个词,TDD(Test-Driven Development)测试驱动开发:在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码

测试驱动开发虽然饱受争议,不过有这种方法论的推出并有不少的同行在践行,起码能够说明测试的重要性

1、当我们想测试部分代码逻辑是否正常的时候,我们可能会直接psvm来构造数据进而调试。那如果有一种东西能把我们psvm统一放到某个地方呢?

2、当我们在一个系统里边修改了很多代码时,又不确定改动是否影响在核心逻辑时。那如果有一种东西能在编译的时候,顺便自动跑一遍逻辑做回归呢?无论是重构还是正式提测前,都提高了自己写代码的信心。

3、当我们很容易一不小心时就把代码写成一坨屎,那如果有一种东西能让我们在编码的时候就注重自己的代码设计呢?

4、当我们这个季度什么都没干,但是系统没发生过故障,那如果有一种东西能让我们在KPI上添上浓墨的一笔呢?

5、....欢迎补充

没错,这东西就是单元测试

写单测好处

慢慢的,我感受到写单测带来的几个好处:

1、提升效率

启动一个应用,几分钟,找bug,修bug,再重启应用,这个过程不断的重复,应用重启太浪费时间。

而单测不需要重启整个应用,只对几个service做测试,效率高很多。

2、场景覆盖全

单测可以对代码运行中的各种情况进行模拟,并对最终的返回结果断言,这是自己自测很难模拟的。而且,这些单测,是沉淀的资产。下次修改代码,可以重跑以前单测,发现问题,避免踩坑。

单测怎么写

我们很容易对单测产生误解,所以这里我先把2个概念说明一下:

1、集成测试

测试过程中,会启动整个Spring容器,调用DB 或者 依赖的外部接口等。只不过访问的环境是测试环境。这个过程最大程度还原生产环境过程,但是耗时长。

2、单元测试

不启动整个应用,只对单个接口/类进行测试。不调用DB 、外部接口,依赖的服务都Mock掉,只测试代码逻辑。这个过程,测试用例耗时短。

我们说的单测,是指第2种。

单测过程分2步,第一步:Mock外部依赖,第二步:断言

Mock框架
1、Mockito单元测试
 <dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>3.3.3</version><scope>test</scope></dependency>
2、Mockito 中文文档地址

Mockito库能够Mock对象、验证结果以及打桩(stubbing)。

GitHub - hehonghui/mockito-doc-zh: Mockito框架中文文档

二、强制要求

1.好的单元测试必须遵守AIR原则
  • A:Automatic(自动化)

  • I:Independent(独立性)

  • R:Repeatable(可重复)

单元测试在线上运行时,感觉像空气(AIR)一样感觉不到,但在测试质量的保障上,却是非常关键的。好的单元测试宏观上来说,具有自动化、独立性、可重复执行的特点。

2.单元测试应该是全自动执行的,并且非交互式的

测试用例通常是被定期执行的,执行过程必须完全自动化才有意义。输出结果需要人工检查的测试,不是一个好的单元测试。

单元测试中不准使用System.out来进行人肉认证,必须使用assert来验证

3.保持单元测试的独立性

为了保证单元测试稳定可靠且便于维护,单元测试用例之间绝不能互相调用,也不能依赖执行的先后次序。

4.单元测试是可以重复执行的,不能受到外界环境的影响。

单元测试通常会被放到持续集成中,每次有代码check in时单元测试都会被执行

如果单测对外部环境(网络、服务、中间件等)有依赖,容易导致持续继承机制的不可用。

正例:为了不受外界环境影响,要求设计代码时就把 SUT 的依赖改成注入,在测试时用 spring 这样的 DI框架注入一个本地(内存)实现或者 Mock 实现。

被测系统

被测系统(System under test, SUT)表示正在被测试的系统,目的是测试系统能否正确操作。

根据测试类型的不同, SUT 指代的内容也不同, 例如 SUT 可以是一个类甚至是一整个系统。

5.对于单元测试,要保证测试粒度足够小。

有助于精确定位问题,单测粒度至多是类级别,一般是方法级别。

6.核心业务、核心应用、核心模块的增量代码,确保单元测试通过。

说明:新增代码及时补充单元测试,如果新增代码影响了原有单元测试,请及时修正。

7.单元测试代码目录

必须写在如下工程目录:src/test/java,不允许写在业务代码目录下。

说明:源码编译时会跳过此目录,而单元测试框架默认是扫描此目录。

三、推荐要求

1.单元测试的基本目标

语句覆盖率达到70%,核心模块的语句覆盖率和分支覆盖率都要达到100%

说明:在DAO层,Manager层和可重用度高的Service中都应该进行单元测试。

分支覆盖率 :5个分支,那么对应的应该有10条语句(一个分支有两条语句,ture和false),如果你执行了其中的5条,那么覆盖率就是50%。

2.编写单元测试代码时遵守BCDE原则,以保证被测试模块的交付质量。
  • B:Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等。

  • C:Correct,正确的输入,并得到预期的结果。

  • D:Design,与设计文档相结合,来编写单元测试。

  • E:Error,强制错误信息输入,并得到预期的结果。

3.对于数据库的相关查询、更新和删除等操作

不能假设数据库里的数据是存在的,或者直接操作数据库将数据插进去,请使用程序插入或者导入数据的方式来准备数据。

4.和数据库相关的单元测试

可以设定自动回滚机制,不给数据库造成脏数据,或者对单元测试产生的数据有明确的前后缀标识。

正例:在企业智能事业部的内部单元测试中,使用 ENTERPRISE_INTELLIGENCE UNIT_TEST 的前缀来标识单元测试相关代码。

5.对于不可测的代码

适当的时机做必要的重构,使代码变得可测,避免为了达到测试要求而书写不规范测试代码。

6.在设计评审阶段

开发人员需要和测试人员一起确定单元测试范围,单元测试最好覆盖所有测试用例。

7.单元测试作为一种质量保障手段

项目提测前完成单元测试,不建议项目发布后补充单元测试用例。

四、参考要求

1.为了更方便地进行单元测试,业务代码应该避免一下情况
  • 构造方法中做的事情过多

  • 存在过多的全局变量和静态方法

  • 存在过多的外部依赖

  • 存在过多的条件语句

说明:多层条件语句建议使用卫语句、策略模式、状态模式等方式重构。

如果条件语句极其复杂,就应该将条件语句拆解开,然后逐个检查,并在条件为真时立刻从函数中返回,这样的单独检查通常被称之为“卫语句”(guard clauses)

摘自《重构---改善既有代码的设计》

卫语句的效果就是将原来需要仔细阅读代码、细心整理逻辑的条件判断整理成一眼能看透的逻辑关系,效果就像以下:

if(obj != null){doSomething();}

转换成卫语句以后的代码如下:

 if(obj == null){return;}​doSomething();
2.不要对单元测试存在如下误解
  • 那是测试同学干的事情。单元测试也是和开发同学强相关的。

  • 单元测试代码是多余的。系统的整体功能和各单元部件的测试真长与否是强相关的。

  • 单元测试代码不需要维护。一年半载后单元测试几乎都会处于废弃朱状态。

  • 单元测试与线上故障没有辩证关系。好的单元测试能够最大限度地规避线上故障。

五、单元测试与集成测试的区别

在实际工作中,不少同学用集成测试代替了单元测试,或者认为集成测试就是单元测试。

单元测试与集成测试的区别:

1.测试对象不同

单元测试对象是实现了具体功能的程序单元,集成测试对象是概要设计规划中的模块及模块间的组合

2.测试方法不同

单元测试中的主要方法是基于代码的白盒测试,集成测试中主要使用基于功能的黑盒测试

3.测试时间不同

集成测试要晚于单元测试。

4.测试内容不同

单元测试主要是模块内程序的逻辑、功能、参数传递、变量引用、出错处理及需求和设计中具体要求方面的测试;而集成测试主要验证各个接口、接口之间的数据传递关系,及模块组合后能否达到预期效果。

六、为什么要使用Mock做测试

比如你现在想要测试一个方法是否是正常的,但是这个方法中有很多调用数据库的代码,那么我们就可以在每个调用数据库的地方打桩模拟一下访问完数据库之后的返回值,这样我们就可以在测试的时候避免访问数据库了,可以非常高效地完成我们的单元测试,已达到验证我们写的方法到底对不对的目的。

1.Mock可以用来解除外部服务依赖,从而保证了测试用例的独立性。

现在的互联网软件系统,通常采用了分布式部署的微服务,为了单元测试某一服务而准备其它服务,存在极大的依耐性和不可行性。

2.Mock可以减少全链路测试数据准备,从而提高了编写测试用例的速度。

传统的集成测试,需要准备全链路的测试数据,可能某些环节并不是你所熟悉的。最后,耗费了大量的时间和经历,并不一定得到你想要的结果。现在的单元测试,只需要模拟上游的输入数据,并验证给下游的输出数据,编写测试用例并进行测试的速度可以提高很多倍。

3.Mock可以模拟一些非正常的流程,从而保证了测试用例的代码覆盖率。

根据单元测试的BCDE原则,需要进行边界值测试(Border)和强制错误信息输入(Error),这样有助于覆盖整个代码逻辑。在实际系统中,很难去构造这些边界值,也能难去触发这些错误信息。而Mock从根本上解决了这个问题:想要什么样的边界值,只需要进行Mock;想要什么样的错误信息,也只需要进行Mock。

4.Mock可以不用加载项目环境配置,从而保证了测试用例的执行速度。

在进行集成测试时,我们需要加载项目的所有环境配置,启动项目依赖的所有服务接口。往往执行一个测试用例,需要几分钟乃至几十分钟。采用Mock实现的测试用例,不用加载项目环境配置,也不依赖其它服务接口,执行速度往往在几秒之内,大大地提高了单元测试的执行速度。

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

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

相关文章

数据驱动营销变革,格力构建数字化会员运营

​作为以大数据和人工智能为核心的新一代数字化服务商&#xff0c;惟客数据基于对企业数字化建设的理解、行业化深耕和产品技术迭代&#xff0c;已助力保利、华润、招商、中海、屈臣氏、格力、喜茶、长城汽车、福田汽车、碧桂园、万科印力、万达、益丰大药房、箭牌、TATA木门、…

【C++】C++11下线程库

C11下线程库 1. thread类的简单介绍2.线程函数参数3.原子性操作库(atomic)4.mutex的种类5. RAII风格加锁解锁5.1Lock_guard5.2unique_lock 6.condition_variable 1. thread类的简单介绍 在C11之前&#xff0c;涉及到多线程问题&#xff0c;都是和平台相关的&#xff0c;比如wi…

Android | ArcGIS入门

一、概述 ArcGIS是由Esri开发的地理信息系统&#xff08;GIS&#xff09;软件。它用于制图、空间分析和数据可视化。ArcGIS允许用户以各种格式创建、管理、分析和共享地理信息。它通常用于城市规划、环境管理和应急响应等领域。该软件包括一系列工具&#xff0c;用于创建地图、…

【GIT学习】仓库过大的清理办法

1、.git目录过大 要解决.git目录过大的问题&#xff0c;可以尝试以下方法&#xff1a; 使用git gc命令清理不再需要的缓存。这将帮助减小仓库的大小。 在命令行中输入以下命令&#xff1a; git gc --prunenow --aggressive使用git repack -ad命令来重新打包已经提交的文件。 …

新年新方案,制造业数字化经营管理平台方案全新升级

伴随着工业4.0和中国智造2025成为制造业领域的两大重要趋势&#xff0c;“推动制造业智能化改造数字化转型”已经到了“不得不”的阶段。 数字化转型能够为制造企业带来降本增效、扩能提质、优化流程、提升竞争力等优势&#xff0c;是建设现代化产业体系的必经之路。 然而&…

CVE-2016-3088(ActiveMQ任意文件写入漏洞)

漏洞描述 1、漏洞编号&#xff1a;CVE-2016-3088 2、影响版本&#xff1a;Apache ActiveMQ 5.x~5.13.0 在 Apache ActiveMQ 5.12.x~5.13.x 版本中&#xff0c;默认关闭了 fileserver 这个应用&#xff08;不过&#xff0c;可以在conf/jetty.xml 中开启&#xff09;&#xff1b;…

【python】linux系统python报错“ssl module in Python is not available”

一、问题现象 1.1 执行pip命令报错 pip安装时遇到openssl问题&#xff0c;没办法安装第三方库 “WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. ” 1.2 导入import ssl 报错 直接执行python&…

C/C++ BM14 链表的奇偶重排

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 解决方案二2.1 思路阐述2.2 源码 总结 前言 这道题算是链表思路的一种常规题&#xff0c;看透题目本质做起来还是不难。 题目 描述 给定一个单链表&#xff0c;请设定一个函数&#xff0c;将链表的奇数位节点和偶数位节点分…

c语言实现bellman-ford算法

下面是使用C语言实现Bellman-Ford算法的示例代码。Bellman-Ford算法用于在带权重的图中找到从单个源点到所有其他顶点的最短路径,它也能处理图中包含负权重边的情况。 #include <stdio.h> #include <stdlib.h> #include <limits.h>// 定义边的结构 struct …

OutLook-2010——管理邮箱的工具

OutLook工具可用于管理邮箱、收发邮件等日常工作&#xff0c;在本书的邮局服务章节要使用到。 下载地址&#xff1a;OutLook-2010——管理邮箱的工具.zip

电脑开机蓝屏错误代码c000021a怎么办 电脑蓝屏报错c000021a的解决办法

很多小伙伴在电脑开机的时候出现蓝屏代码c000021a都不知道该怎么去解决&#xff0c;所以今天就给你们带来了c000021a蓝屏解救方法&#xff0c;如果你还没解决的话就快来看看吧。 解决办法&#xff1a; 原因&#xff1a; c000021a蓝屏的原因有很多&#xff0c;主要有以下几种…

四非保研之旅

大家好&#xff0c;我是工藤学编程&#xff0c;虽有万分感概&#xff0c;但是话不多说&#xff0c;先直接进入正题&#xff0c;抒情环节最后再说&#xff0c;哈哈哈 写在开头 我的分享是来给大家涨信心的&#xff0c;网上的大佬们都太强了&#xff0c;大家拿我涨涨信心&#…

【项目实践-03】实验室PC

透传属性 透传属性指组件在使用的时候&#xff0c;作用在组件上的属性&#xff0c;会被向下流动&#xff0c;绑定到组件内的标签中。 可以透传的属性&#xff1a;style&#xff0c;class&#xff0c;id&#xff0c;属性&#xff0c;事件 当一个组件有多个根标签节点时&#xf…

Spring Framework

Spring Framework Spring 是一款开源的轻量级 Java 开发框架&#xff0c;旨在提高开发人员的开发效率以及系统的可维护性。 Spring 框架指的都是 Spring Framework&#xff0c;它是很多模块的集合&#xff0c;如下图所示&#xff1a; 一、Core Container Spring 框架的核心模…

Android的消息机制--Handler

一、四大组件概述 Android的消息机制是由Handler、Message、MessageQueue&#xff0c;Looper四个类支撑&#xff0c;撑起了Android的消息通讯机制&#xff0c;Android是一个消息驱动系统&#xff0c;由这几个类来驱动消息与事件的执行 Handler&#xff1a; 用来发送消息和处…

纯css实现文字左右循环滚动播放效果

思路&#xff1a;由两个span模块组成&#xff0c;第一个为空的span内容&#xff0c;为的是实现第二个span内容缓慢出现的效果。 代码如下&#xff1a; <div class"scrollingStyle"><span class"first-marquee"></span><span class&q…

Samba是什么?有什么作用?工作流程以及如何搭建

前言&#xff1a; 寒假在家学习Linux近一个月了&#xff0c;最近参加了嘉立创组织的泰山派训练营&#xff0c;从中了解到了现在Linux开发中很方便的一些开发方式和工具。例如&#xff1a;使用MobaXterm终端通过SSH登陆ubuntu服务器进行开发&#xff1b;安装一个FileZilla工具通…

定制线缆厂家推荐:赋能科技互联,精工电联的集成线缆定制服务(小批量、多品类产品高效解决方案)

定制线缆 精工电联&#xff1a;赋能科技互联&#xff0c;精工电联的集成线缆定制服务&#xff08;小批量、多品类产品高效解决方案&#xff09; 随着科技的飞速发展&#xff0c;人们对数据传输速度和稳定性的需求日益增强。精工电联作为高科技智能化产品及自动化设备专用连接线…

第二证券:汽车产业链股爆发,中通客车涨停,星源卓镁等大涨

轿车产业链股21日盘中强势拉升&#xff0c;截至发稿&#xff0c;华阳变速涨超29%&#xff0c;星源卓镁涨超15%&#xff0c;德迈仕涨逾10%&#xff0c;中捷精工、中通客车、合力科技、圣龙股份等涨停。 行业方面&#xff0c;中国轿车工业协会近来公布数据显示&#xff0c;1月&a…

【快速搞定Webpack5】介绍及基本使用(一)

webpack 是一个静态资源打包工具。 他会以一个或多个文件作为打包的入口&#xff0c;将我们整个项目所有文件编译组合成一个或多个文件输出出去。 输出的文件就是编译好的文件&#xff0c;就可以在浏览器端运行了。 我们将 webpack 输出的文件叫做 bundle 。 (将浏览器不识别的…