一看到"测试先行"、"测试驱动"这样的名字,就深深地激起了我强烈的好奇心,开始了自己的探索之旅..
心灵震憾
一段时间的学习,让我的内心受到了深深的震撼。我们原来的方法居然如此的笨我面对软件测试先行这一名字时,当时最大的疑问就是"程序都还没有写出来, 测试什么呀!"。后来一想,其实这是一个泥瓦匠都明白的道理,却是自己在画地为牢。我们来看看两个不同泥瓦匠是
如何工作的吧:
工匠一:先拉上一根水平线,砌每一块砖时,都与这根水平线进行比较,使得每一块砖都保持水平。
工匠二:先将一排砖都砌完,然后拉上一根水平线,看看哪些砖有问题,再进行调整。
你会选择哪种工作方法呢?你一定会骂工匠二笨吧!这样多浪费时间呀! 然而你自己想想,你平时在编写程序的时候又是怎么做的呢?我们就是按工匠二的方法在干活的呀!甚至有时候比工匠二还笨,是整面墙都砌完了,直接进行"集成测试",经常让整面的墙倒塌。看到这里,你还觉得自己的方法高明吗?
单元测试长期以来被忽视
每一个程序员都知道应该为自己的代码编写测试程序,但却很少这样做。当人们问为什么的时候,最常听到的回答就是:"我们的开发工作太紧张了"。但这样却导致了一个恶性循环,越是没空编写测试程序,代码的效率与质量越差,花在找Bug、解决Bug的时间也越来越多, 实际效率大大降低。由于效率降低了,因此时间更紧张,压力更大。你想想,为什么不拉上一根水平线呢?难道,我们不能够将后面浪费的时间花在单元测试上,使得我们的程序一开始就更加健壮,更加易于修改吗?抛弃原来的托词吧!
我们的自动化水平太低了
有人还会解释说,那是因为拉根水平线很简单,而写测试程序却是十分复杂的。我暂且对这句话本身不置可否。不过也体现了一个新问题,我们需要更加方便、省时的编写测试程序的方法。
要测试一个类,最简单的方法是直接在调试器中使用表达式观察对象的值与状态,你也可以在程序中加上一些断言、打印中间值等,当然还可以编写专门的测试程序。但是这些方法都有一个很大的局限性,都需要加入人工的判断和分析。
由此,自动化测试的引入才是解决之道。正是因为如此,提倡"测试驱动开发"的人群,开发出一系列的自动化单元测试框架xUnit,现在已经有针对Java、Pyhton、C++、PHP等各种常用语言的测试框架。这足以搪塞住那些以"编写测试代码太麻烦"为理由的开发人员,让他们没有理由逃避单元测试。
正如Robert Martin所说:"测试套件运行起来越简单,就会越频繁地运行它们。测试运行越多,就会越快地发现和那些测试的任何背离。如果能够一天多次地运行所有的测试,那么系统的失效时间就决不会超过几分钟"。
认清测试驱动开发
测试驱动开发理论最初源于对这些问题的思考:
1)如果我们能够在编写程序代码之前先进行测试方案的设计,会怎样?
2)如果我们保证除非没有这个功能将导致测试失败,否则就不在程序中实现该功能,会怎样?
3)换一个角度,如果当测试时发现必须增加某项功能才能够通过测试时, 我们就增加这一功能,会怎样?
大师们通过带着这些问题的实践, 发现这的确是一个提高软件代码质量, 使得效率得到保障的一个很好出发点。