前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单元测试

单元测试

原创
作者头像
MickyInvQ
修改2021-02-07 10:50:06
7900
修改2021-02-07 10:50:06
举报
文章被收录于专栏:InvQ的专栏InvQ的专栏

单元测试

单元测试的意义

单测好处:

  • 单元测试使工作完成的更轻松
  • 单元测试使你的设计更好
  • 大大减少花在调试上的时间
  • 能帮助你更好的理解代码

单元测试是什么?

指对软件中最小的可测试单元进行检查和验证,调用被测服务的类或方法,根据类或方法的参数,传入相应的数据,得到一个返回结果,最终断言返回的结果是否符合预期。如果相等,测试通过;如果不相等,测试失败。

所以,单元测试关注的是代码的实现与逻辑。单元测试是最基本的测试,也是测试中的最小单元,它的对象是函数对象,也可以包含输入输出,针对的是函数功能或者函数内部的代码逻辑,并不包含业务逻辑。

该类测试一般由研发人员完成,需要借助单元测试框架,如java的Junit、TestNG,mockito,python的unittest等

好的单元测试准则

1.运行快速

单元测试运行比较频繁,如果打包时候,单元测试运行很慢,会很影响效率。

  • 单个测试小于200ms
  • 单个测试套件小于10s
  • 整个测试小于10分钟

2.一致性

任何时候,同样的输入需要同样的结果。

3.原子性

所有的测试只有两种结果:通过和未通过。不能存在部分测试通过的情况

4.单一职责

一个测试只验证一个行为。

  • 一个方法,多个行为->多个测试
  • 一个行为,多个方法->一个测试(一个行为,多个方法一般指该方法调用private,protected,getters,setters)
  • 多个assert只有在测试一个行为时可以接受

5.独立无耦合

单元测试之间无相互调用

  • 单元测试执行顺序无关
  • 不同顺序无影响

单元测试之间不能共享状态

  • 比如不能共享变量,如果需要,放在setup里

6.隔离外部调用

  • 单元测试需要快速运行,且每次结果一致,所以需要隔离一切对外部的调用
  • 不使用具体的其它真实类(就是不要new)
  • 不读数据库
  • 不读网络
  • 不读外部文件
  • 适当时候可构建相同的内部文件mock
  • 不依赖本地时间
  • 不依赖环境变量

7.自描述

  • 单元测试是开发级文档
  • 单元测试是方法的描述

8.单元测试逻辑

  • 单元测试必须容易读和理解
  • 变量名,方法名,类名
  • 无条件语句,无swith(分解if到多个测试,所有的输入都是已知的,所有的结果都是一定的,可以mock)
  • 无循环语句
  • 无异常捕捉(测试预知的异常,用ExpectedException方法)

9.产品代码

  • 产品代码不能有测试逻辑
  • 测试代码和产品代码要分离
  • 使用依赖注入
  • 不要在产品代码里有任何只供测试的代码

根据上述指导思想和实际实现情况,一般在实现单元测试时有两种不同的实现方式

  • 单层隔离
  • 内部穿透

单层隔离

正常代码分层会分为controller、service、dao等,在单层隔离的思想中,是针对每一层的代码做各自的单元测试,不向下穿透。这样的写法主要是保证单层的业务逻辑固化且正确。

实践过程中,例如针对controller层编写的单元测试需要将对应controller类代码文件外部所有的调用全部mock,包括对应的内部/外部的service。其他层的代码也是如此。(可以参考样例代码中cdo-test-sample-core层的单测代码)

好处

  • 单元测试代码极其轻量,运行速度快
  • 真正符合了单元测试的原则,可以在断网的情况下进行运行,屏蔽服务注册和配置管理,各种中间件的影响
  • 单元测试质量更高

缺点

  • 单元测试的代码量比较大
  • 对于低复杂度的项目比较不友好(例如项目是单纯分层之后的CRUD)

内部穿透(集成测试)

穿透,自然就是从顶层一直调用到底层,为什么还要加上内部二字?就是除了项目内的方法可以穿透,项目外部依赖还是要mock掉。实践过程中,就是单元测试针对controller层编写,但会完整调用service、dao,最终对落地结果进行验证。(可以参考样例代码中cdo-test-sample-api层的单测代码)

好处

  • 代码量相对较小
  • 学习曲线低,穿透的单元测试更偏向黑盒,开发人员构造输入条件,然后从落地结果中验证预期结果

缺点

  • 整体较重,启动spring容器,中间件mock,整体单元测试运行预计需要分钟级别。所以基本是要在ci的时候来执行
代码语言:txt
复制
   这两种方法,具体使用哪种合适,应该由项目成员根据项目实际情况自行选择,一般建议核心项目两种执行方法都可以同时执行,具体实施时可以先执行“单层隔离”积累单测用例,再做“内部穿透”。
代码语言:txt
复制
   PS:我们一般使用@SpringBootTest注解进行集成测试,使用其它spring test(@WebMvcTest)注解进行特定组件的单元测试。

参考文档:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单元测试
    • 单元测试的意义
      • 单元测试是什么?
        • 好的单元测试准则
          • 单层隔离
            • 内部穿透(集成测试)
            相关产品与服务
            消息队列 TDMQ
            消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档