单元测试-【转】论单元测试的重要性

本文章转自:http://www.51testing.com/html/00/n-3724000.html ,只供学习使用。

系列导航

点击跳转到系列博文目录导航

1 什么是单元测试

单元测试是对软件组成单元进行测试,其目的是检验软件基本组成单位的正确性,测试的对象是软件设计的最小单位:函数。(维基百科)

2 单元测试不是集成测试

这里需要强调一个观念,那就是单元测试只是测试一个方法单元,它不是测试一整个流程。举个例子来说,一个Login页面,上面有两个输入框和一个button。两个输入框分别用于输入用户名和密码。点击button以后,有一个UserManager会去执行performlogin操作,然后将结果返回,更新页面。

那么我们给这个东西做单元测试的时候,不是测这一整个login流程。这种整个流程的测试:给两个输入框设置正确的用户名和密码,点击login button, 最后页面得到更新。叫做集成测试,而不是单元测试。当然,集成测试也是有他的必要性的,然而这不是我们每个程序员应该花多少精力所在的地方。在这方面,有一个理论叫做Test Pyramid,如下图所示:
在这里插入图片描述
Test Pyramid理论基本大意是,单元测试是基础,是我们应该花绝大多数时间去写的部分,而集成测试等应该是金字塔上面能看见的那一小部分。

为什么是这样呢?因为集成测试设置起来很麻烦,运行起来很慢,发现的bug少,在保证代码质量、改善代码设计方面更起不到任何作用,因此它的重要程度并不是那么高,也无法将它纳入我们正常的工作流程中。

而单元测试则刚好相反,它运行速度超快,能发现的bug更多,在开发时能引导更好的代码设计,在重构时能保证重构的正确性,因此它能保证我们的代码在一个比较高的质量水平上。同时因为运行速度快,我们很容易把它纳入到我们正常的开发流程中。

至于为什么集成测试发现的bug少,而单元测试发现的bug多,这里也稍作解释,因为集成测试不能测试到其中每个环节的每个方面,某一个集成测试运行正确了,不代表另一个集成测试也能运行正确。而单元测试会比较完整的测试每个单元的各种不同的状况、临界条件等等。一般来说,如果每一个环节是对的,那么在很大的概率上,整个流程就是对的。虽然不能保证整个流程100%一定是对的。所以,集成测试需要有,但应该是少量,单元测试是我们应该花重点去做的事情。

很多时候大家会把单元测试跟集成测试搞混, 其实只要记住单元测试面向的对象是最小程序单元: 函数,它是面向软件应用开发者而言的, 而集成测试一般是面向测试人员进行黑盒测试的,不是开发者重点关注的地方。

3 为什么很多人不写单元测试

网上有些文章关于这个问题做了一些讨论, 我把原因贴出来:

  • 不知道怎么编写单元测试
  • 单元测试价值不高,完全是浪费时间
  • 业务逻辑比较简单,不值得编写单元测试

说实话,在着手去看单元测试之前,上面的原因我基本上也都存在,相信很多人跟我有同样的想法.
但是细看这些原因归根结底就是不了解单元测试,下面根据网上的文章和我自己理解去反驳这些观点.
1:不知道怎么编写单元测试
  这肯定是没有接触过单元测试,根本不了解单元测试会带给你什么,你能从中得到什么益处. 设想一下,当你开发完一个功能模块的时候,你如何确定你的模块没有 bug 呢?如果涉及到具体的业务,你会执行 debug 模式,然后一点一点的深入到代码中去查看吗?如果你一直都是这样,那么你早就已经 OUT 了。赶快去了解一下单元测试的工具吧,你会收获很大的。这在Android开发中更是非常"蛋疼"的,每次项目编译执行少则2-3分钟,多则可能十几分钟,如果每次都是真机调试会耽误大量的时间在上面.
2:单元测试价值不高,完全是浪费时间
  这种说法其实是错误的。为什么这么说呢?在日常的开发中,代码的完工其实并不等于开发的完工。如果没有单元测试,那么如何保证代码能够正常运行呢?测试人员做的只是业务上的集成测试,也就是黑盒测试,对单个的方法是没有办法测试的,而且,测试出的 bug 的范围也会很广,根本不能确定 bug 的范围,还得去花时间来确定 bug 出在什么地方。难道这就不浪费时间了吗?甚至,这样的方式,时间浪费的会更多。
3:业务逻辑比较简单,不值得编写单元测试
  所谓的业务逻辑比较简单,其实是相对的。当你对某一块业务逻辑很熟悉的时候,你自然会认为它很简单。然而,单元测试的必要性并不是仅仅在于测试代码的功能是否正确,还在于,当其他同事在了解你的业务的时候,能够很快的通过单元测试来熟悉代码的功能,甚至不用去读代码,就能够知道它做了哪些事情。因此,写单元测试不仅是解放了自己,更方便了别人。

4 TDD 测试驱动开发

在这里插入图片描述
  Test-Driven Development, 测试驱动开发, 是敏捷开发的一项核心实践和技术,也是一种设计方法论。TDD原理是开发功能代码之前,先编写测试用例代码,然后针对测试用例编写功能代码,使其能够通过。由于TDD对开发人员要求非常高,跟传统开发思维不一样,因此实施起来相当困难。
  测试驱动开发有好处也有坏处。因为每个测试用例都是根据需求来的,或者说把一个大需求分解成若干小需求编写测试用例,所以测试用例写出来后,开发者写的执行代码,必须满足测试用例。如果测试不通过,则修改执行代码,直到测试用例通过。
  好处,通过测试的执行代码,肯定满足需求,而且有助于接口编程,降低代码耦合,也极大降低bug出现几率(如果是极限编程,几乎是不可能有bug)。
  坏处,1.投入开发资源(时间和精力);2.由于测试用例在未进行代码设计前写;很有可能限制开发者对代码整体设计
  Note: 个人认为我们也没有必要完全按照TDD模式进行开发, 但是这种思想是需要我们借鉴的,在有很多复杂逻辑处理的地方应用这种开发模式还是非常有必要的.

5 单元测试工具

既然单元测试如此重要,那我们使用哪种单元测试工具呢?
对于pure Java代码来说, 采用JUnit做基础的单元测试框架, Mockito用来mock对象等,AssertJ丰富断言支持等。

猜你喜欢

转载自blog.csdn.net/CSDN___LYY/article/details/86571665
今日推荐