当前位置:网站首页 > 单元测试 > 正文

单元测试的基本要求(单元测试的原则有哪些)



        说起单元测试,每个开发人员都很熟悉,但并未得到大家的重视。很多开发人员认为单测属于可有可无,意义不大。或者有时间就写,没时间就算了的情况。甚至认为:“反正有测试同学帮忙把控代码质量,为什么还要开发浪费时间写单测呢?难道不是重复工作么?”这个问题其实很有代表性,很多开发有这个想法,就算他们写了单测,可能也只是敷衍了事或者随意发挥。

        这里解释一下前言中的几个关键点:

  1. 职责的不同。开发人员的职责是在保证质量的前提下完成一个功能的开发,而测试人员的职责是为产品的质量把关,保证项目交付的质量。也就是说保证代码质量是开发这一环节的工作职责之一,在测试阶段发现了代码里的过多缺陷,就说明了一些场景未考虑全面。
  2. 成本的不同。对于同一个缺陷,在越早期发现,修复的成本就越小,这个道理想必大家都知道。如果很多的质量问题,都需要到测试阶段才能发现,才来返工修复,这对整体项目的时间和资源来说绝对是不小的浪费。
  3. 角度的不同。对于开发人员来说,写单测更多的是针对单个方法的逻辑的测试,而对于测试人员来说,更多的是针对功能的黑盒测试,而单测能够覆盖到某些特殊场景。

        在面向对象语言里,一个方法到一个类,都可以是一个单元,它取决于我们的测试意图。

        在Google官方文档中,将测试分为三级,最底层的属于小型测试即单元测试,本文以单测简称之,第二层属于中型测试即集成测试,第三层属于大型测试即UI测试,每一层的比例约为小型测试占 70%,中型测试占 20%,大型测试占 10%。

  1. 小型测试:针对单个函数的测试,关注其内部逻辑,mock所有需要的服务。小型测试带来优秀的代码质量、良好的异常处理、优雅的错误报告。
  2. 中型测试:验证两个或多个制定的模块应用之间的交互。
  3. 大型测试:也被称为“系统测试”或“端到端测试”。大型测试在一个较高层次上运行,验证系统作为一个整体是如何工作的。

        你是不是也有这些疑问?

  • 单测浪费了太多的时间
  • 单测仅仅是证明这些代码做了什么
  • 我是很棒的程序员,我是不是可以不进行单测?
  • 后面的集成测试将会抓住所有的bug
  • 单测的成本效率不高我把测试都写了,那么测试人员做什么呢?
  • 公司请我来是写代码,而不是写测试
  • 测试代码的正确性,并不是我的工作
  • 只是 Bug 少了一点

        据统计,大约有80%的错误是在软件设计阶段引入的,并且修正一个软件错误所需的费用将随着软件生命期的进展而上升。错误发现的越晚,修复它的费用就越高,而且呈指数增长的趋势。作为编码人员,也是单测的主要执行者,是唯一能够做到生产出无缺陷程序这一点的人,其他任何人都无法做到这一点。 

        上面那张图,来自微软的统计数据:bug在单测阶段被发现,平均耗时3.25小时,如果漏到系统测试阶段,要花费11.5小时。

        下面这张图,旨在说明两个问题:85%的缺陷都在代码设计阶段产生,而发现bug的阶段越靠后,耗费成本就越高,指数级别的增高。

 

        那么单测的作用到底是什么?意义究竟如何体现?

  1. 单测可以很好保证代码质量,一个好的单测能够覆盖各种业务场景,在这个前提下该目标单元都能够验证通过,说明该单元是足够健壮的。
  2. 单测可以一定程度提高代码合理性,当我们发现给一个方法写单测非常困难,比如需要覆盖的业务场景过多,那说明此方法可以在一定程度上继续进行拆分;又比如需要mock的内容过多,那说明此方法违背了单一责任原则,处理了太多的逻辑,那么需要重新设计等等。
  3. 单测能够有效防止回溯问题的出现,提升回归测试的质量,随着功能的不停增加,全量回归性价比会越来越低,测试人员仅会对主流程进行测试,对于那些不在测试范围内的边界功能,单测能够进行覆盖从而提升回归测试的质量。
  4. 通过单测快速熟悉代码,单测不仅起到了测试的作用,还是一种很好的“文档”,通过单测代码,我们不需要深入的阅读代码,便能知道这段代码做什么工作,有哪些特殊情况需要考虑,包含哪些业务。

小结:对于单测,我们不搞虚的,希望能实实在在为项目质量保驾护航。

  1. 针对逻辑复杂、核心的业务去写单测
  2. 针对痛点、易错的代码去写单测
  3. 针对不易理解的代码去写单测
  4. 针对改动较多的部分去写单测

        单测是指对软件中的最小可测试单元进行检查和验证,要以类功能作为测试目标的单个或者一连串的函数测试,也就是说,单测可以是对某个类的具体函数的功能、内部逻辑进行验证。

        而针对代码复杂性和依赖性,有如下图的原则描述可参考:

  1. 第一象限复杂依赖多:重构减少依赖,变成复杂依赖少,然后写单测
  2. 第二象限复杂依赖少:适合写单测
  3. 第三象限简单依赖少:看情况写
  4. 第四象限简单依赖多:不用重构,不用单测

        这里对第四象限多提一嘴,对它们写单测意义并不大,不要为了提高单测覆盖率,而花费很多时间和精力去写单测,这样得不偿失。

        比较好的节奏是:每个功能Sprint的开发周期,单测与具体实现代码同时进行。

        首先,单测成长的过程大致可分为如下4个阶段:

  1. 会写,全员写,不要求写好。
  2. 写好,有效。关注可测性问题,试点解决
  3. 可测试性提升。识别可测性问题,熟练使用重构方法进行重构;识别代码架构设计问题;case与业务代码同步编写
  4. TDD。但这个目标是期望,不能作为必须实现的目标。

        我们代码中经常会有日期工具类,下面是对获取有效日期的测试例子。

(1)获取有效日期源码

 

(2)单元测试代码

        我们对边界情况(日期小于0、等于0),和正常情况(日期大于0)分别进行测试,单测代码如下:

 

        当传入日期小于0或等于0时,获取到的有效日期为当前时间戳;

        当传入日期大于0时,获取到的有效日期为传入日期。

注:为简化Demo,这里我们假定,程序多次获取当前时间戳是一样的。

(3)单元测试三段式

        上面是很经典的测试写法,也有很多人称这种写法为“三段式”,“三段式”包括模拟前提、执行语句、断言结果。

        上面测试例子中,time1 和 time2的创建就是模拟前提,例子中最后一行把执行语句和断言合在了一起,分解开来的话就是:

        val validDate2 = DateUtils.getValidDate(time2)

        Assert.assertEquals(time2, validDate2)

        终端应用中,通常会存在页面跳转逻辑,通过传入不同的参数类型,跳转不同页面,下面我们来一起看看。

(1)页面跳转逻辑源码

 

(2)代码重构

 

        此处我们只关注skipType的输入,会导致什么样的输出,所以对具体实现细节我们可以封装起来,这也是软件设计中最少知道原则的使用。

(3)单元测试代码

 

        可以看到,我们依旧使用的是单元测试三段式:首先,模拟输入,构造skip对象,并且mock真实的goToUgcMapDetail方法调用,做到逻辑隔离与单一验证;然后,调用npcHandlePush方法,根据模拟的输入,应该会调用goToUgcMapDetail方法;最后,验证goToUgcMapDetail方法是否执行,即可。

  • bug类指标(间接指标):连续迭代的bug总数趋势、迭代内新建bug的趋势、千行bug率
  • 单测的需求覆盖度(50%以上),参与人员覆盖度(80%以上)
  • 单测case总数趋势,代码行增量趋势
  • 增量代码的行覆盖率(接入层80%,客户端30%)
  • 单函数圈复杂度(低于40),单函数代码行数(低于80),扫描告警数

其实,单测的关键成果,并没那么好衡量,需要团队根据自身情况去做出选择


        如果一个对象具有以下特征,比较适合使用mock对象:

  • 该对象提供非确定的结果(比如当前的时间或者当前的温度)
  • 对象的某些状态难以创建或者重现(比如网络错误或者文件读写错误)
  • 对象方法上的执行太慢(比如在测试开始之前初始化数据库)
  • 该对象还不存在或者其行为可能发生变化(比如测试驱动开发中驱动创建新的类)
  • 该对象必须包含一些专门为测试准备的数据或者方法(后者不适用于静态类型的语言,流行的Mock框架不能为对象添加新的方法。Stub是可以的。)

        因此,不要滥用mock(stub),当被测方法中调用其他方法函数,第一反应应该走进去串起来,而不是从根部就mock掉了。

        【Android 单元测试,从小白到入门开始_Swuagg的博客-CSDN博客_android 单元测试教程】

        【从头到脚说单测——谈有效的单元测试 - 云+社区 - 腾讯云】

到此这篇单元测试的基本要求(单元测试的原则有哪些)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 单元测试项目(单元测试过程是怎样的?)2025-05-12 23:45:10
  • 单元测试的范围是什么(单元测试范围包括)2025-05-12 23:45:10
  • 单元测试依据是什么意思(单元测试依据是什么意思呀)2025-05-12 23:45:10
  • 单元测试 规范(单元测试步骤及测试内容)2025-05-12 23:45:10
  • 单元测试规范(单元测试规范文档)2025-05-12 23:45:10
  • 单元测试项目(单元测试包含哪些内容?有哪些需要检测的)2025-05-12 23:45:10
  • 单元测试步骤及测试内容(单元测试的一般步骤)2025-05-12 23:45:10
  • 单元测试规范文档模板(单元测试标准规范)2025-05-12 23:45:10
  • 单元测试方案(单元测试步骤)2025-05-12 23:45:10
  • 单元测试方案怎么写(单元测试方案怎么写的)2025-05-12 23:45:10
  • 全屏图片