博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
软件开发中的形式主义--单元测试
阅读量:6566 次
发布时间:2019-06-24

本文共 1712 字,大约阅读时间需要 5 分钟。

hot3.png

在我写下这个标题的时候我就知道就会被人丢板砖,但是没关系我一点都不怕,我知道挑战成见是一件吃力不讨好的事情,但我必须忠于自己的良心和思维

装逼第二弹单元测试

在许久以前,大家写完一段代码后都会在代码下面写一个main方法来调用一下刚刚写过的代码,然后检查刚刚写的代码正确与否。随着类和方法越来越多,这样的main方法也越来越多。这样会出现两个问题

  1. 测试代码和正常的逻辑代码混在一起,导致混乱

  2. 为了测试到所有的类,必须把每个类都手动执行一遍,比较费时费力

因此就有人发明的单元测试框架如大名鼎鼎的junit,有了它,我们的机械劳动就少了很多,我们的代码就清爽了很多。

-----------but  分割线----------

本来junit这种测试框架只是为了减轻我们的机械劳动,但是一些"技术大拿"们却把它用在了软件质量控制上面,他们规定代码的单元测试覆盖率必须达到某个比例,如果达不到就要批评,就认为软件质量不过关。他们的逻辑是,单元测试覆盖到的代码才能有质量保证,没有覆盖到的代码,正确性完全不可知。这样的尝试还是值得鼓励的,但是把单元测试覆盖率上升到一个严苛和非常重要的程度就有点迂腐和装逼了。

原因如下

1。单元覆盖低的代码并不一定质量低下。

测试代码的方法很多,单元测试只是其中一种而已,而且这还是只是局部测试方法而已。集成测试一样可以确保软件的正确性,而且集成测试对软件质量的保证的效率远远大于单元测试,通过的集成测试的软件基本就是一个功能上可用的软件,而经过单元测试的软件离软件可用还有很远的距离。

2。单元测试覆盖率根本不等同于代码单元的正确率

一个单元测试覆盖率很高的代码可能是非常垃圾的代码。看看下面的代码就可以看得出来。

//正常逻辑      public Integer compute(List
 nums) { return nums.get(0) + nums.get(1) + nums.get(2) + nums.get(3);}       //测试代码      @Testpublic void testCompute() { List
 num = Arrays.asList(1, 2, 3, 4); assert ConsoleAction.compute(num) == 10;}

 

 

上面的代码单元测试覆盖率是100%,但却是一段非常糟糕的代码,当list的size<4的时候,系统就会报越界错误

可以看得出来代码的质量和单元测试覆盖率是没有那么直接的关系。并且这种代码的质量和覆盖率的无关性会随技术官僚作风严重性或装逼的严重呈正比。因为当把单元测试覆盖率本身作为一个团队质量的衡量标准的时候,程序猿们就不会关心单元测试能不能测出bug,只会关心测试覆盖率能不能达到 100% ,于是最终出现的结果是团队之间比较的不是软件本身的质量,比较的只是一个覆盖率而已。

因此单元测试覆盖率只适合推广宣传鼓励,并不适合于强力执行。一旦强力执行他就会变味。

而且"技术大拿"们真的没有必要在单元测试覆盖率上死磕不放,因为真正的绝大多数的 bug都是在专门的测试阶段测试出来的,这个关把好了,软件质量不会有问题。

-------- 团队现状-----------

我经历过的好些个项目的单元测试都不是那么好,原因很明显写单元测试并不是一个轻松省力的活。测试DAO层要用专门的DBtest,还要用excel专门的构造测试数据集,测试service要用配置专门的bean的xml,远程接口还要专门的写mock。这些都是非常麻烦的事情。

更省力的办法的是,测试DAO时直接在测试数据离构造测试数据,然后触发dao,测试service的时候直接在test环境下触发并debug。虽然这种方法很土但很管用很快速。虽然这种方法在"技术大拿"们看来单元测试覆盖率为0,很不符合要求,但这其实是用另外一种方式完成了单元测试,保证的单元的正确性。

转载于:https://my.oschina.net/chenzuoping/blog/164052

你可能感兴趣的文章
12月26日二周二次【Python基础语法】
查看>>
Android L 新特性
查看>>
学习笔记第十七节课
查看>>
Python 爬取图片链接并且解析
查看>>
初学图论-Bellman-Ford单源最短路径算法
查看>>
初学算法-快速排序与线性时间选择(Deterministic Selection)的C++实现
查看>>
NFS网络文件系统
查看>>
SSH远程管理(用户登录控制及密码验证)
查看>>
java常用类型转换
查看>>
划分vlan,制作trunk口。使同一vlan能互相通讯
查看>>
地理信息系统控件GIS控件TatukGIS Developer Kernel 下载及介绍
查看>>
VIM的snipMate的继承设置
查看>>
云HBase发布全文索引服务,轻松应对复杂查询
查看>>
DNS
查看>>
小清新简约风个人简历PPT模板
查看>>
深度剖析数据在内存中的存储1——数据类型
查看>>
深度剖析数据在内存中的存储2——浮点数数在内存中的存储
查看>>
进行将多张CAD图纸转换成高清WMF格式的操作是什么?
查看>>
如何在三个月学习三年的生活经验
查看>>
简单的dns解析过程
查看>>