文档章节

软件开发中的形式主义--单元测试

loveczp
 loveczp
发布于 2013/09/25 12:30
字数 1393
阅读 60
收藏 0

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

装逼第二弹单元测试

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

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

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

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

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

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

原因如下

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

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

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

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

//正常逻辑
      public Integer compute(List<Integer> nums) {
	return nums.get(0) + nums.get(1) + nums.get(2) + nums.get(3);
}


       //测试代码
      @Test
public void testCompute() {
	List<Integer> 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,很不符合要求,但这其实是用另外一种方式完成了单元测试,保证的单元的正确性。

© 著作权归作者所有

共有 人打赏支持
loveczp

loveczp

粉丝 13
博文 7
码字总数 6427
作品 1
武汉
程序员
私信 提问
complete_code_Chapter1

《代码大全》读书笔记 Chapter 1 Welcome to Software Construction 第一章 欢迎进入软件构建的世界 What Is Software Construction 什么是软件构建 开发计算机软件已是一个复杂的过程。在软...

Frost729
08/02
0
0
Python自动单元测试框架

简介: 软件的测试是一件非常乏味的事情,在测试别人编写的软件时尤其如此,程序员通常都只对编写代码感兴趣,而不喜欢文档编写和软件测试这类"没有创新"的工作。既然如此,为什么不让程序员...

长平狐
2013/01/06
33
0
单元测试和测试驱动开发 TDD 是怎么回事?

对于测试驱动开发和单元测试,我总有一种既爱又恨的感情在里面。 我一直都是这些“最佳实践”的热心支持者,但是我对它们的使用也一直持有怀疑态度。 软件开发中最大的问题之一是开发者或管理...

班纳睿
10/10
0
0
单元测试入门

在我们Java软件开发过程中,相应的测试也在有序穿插的进行着;在软件公司中称之为单元测试,单元测试,顾名思义:就是对一个个小的独立的功能模块进行测试,我们常用的单元测试工具有很多种,...

阿狸的老大是悟空丶
2016/10/25
4
0
基于测试驱动的iOS开发

测试按照阶段划分为:单元测试、集成测试、系统测试和回归测试。单元测试是对软件组成单元进行测试,其目的是检验软件基本组成单位的正确性,其测试对象是软件设计的最小单位——模块。单元测...

HelloSwift
2016/08/09
13
0

没有更多内容

加载失败,请刷新页面

加载更多

使用 React 和 Vue 创建相同的应用,他们有什么差异?

在工作中应用 Vue 之后,我对它有了相当深刻的理解。 不过,俗话说「外国的月亮比较圆」,我好奇「外国的」 React 是怎么样的。 我阅读了 React 文档并观看了一些教程视频,虽然它们很棒,但...

阿K1225
12分钟前
0
0
如何使用Kubernetes的configmap通过环境变量注入到pod里

在Kubernetes官网里,有这样一篇文章,提到了Kubernetes里的一个最佳实践就是把应用代码同配置信息分开,一种方式就是使用Kubernetes 1.2里引入的configmap概念。 https://kubernetes.io/bl...

JerryWang_SAP
27分钟前
0
0
2天闭门培训|以太坊智能合约从入门到实战(北京)

2天培训 16个课时 探寻技术原理,精通以太坊智能合约开发 以太坊智能合约是现在应用的最广泛的区块链应用开发方式,HiBlock区块链社区针对以太坊智能合约的学习特别推出2天闭门研修班,通过2...

HiBlock
30分钟前
0
0
限定某个目录禁止解析php,限制user_agent,php相关配置

11月20日任务 11.28 限定某个目录禁止解析php 11.29 限制user_agent 11.30/11.31 php相关配置 1.限定某个目录禁止解析php 核心配置文件内容 <Directory /data/wwwroot/www.123.com/upload> p...

hhpuppy
41分钟前
2
0
Spring的好文章

孤傲苍狼 https://www.cnblogs.com/xdp-gacl/p/4249939.html 跟我学spring http://jinnianshilongnian.iteye.com/blog/1413846 SpringIoc 和Spring Aop 代理模式: 静态代理 动态代理 cglib代......

wangwei2134
52分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部