TDD(测试驱动开发)

为什么我们需要单元测试

2017-12-14  本文已影响100人  柴诗雨

程序猿的时间都花在哪儿了

程序猿是一种很神奇的生物,他们对于大自然的主要贡献是把垃圾食品和碳酸饮料转换为代码。那么这种生物每天的时间是如何度过的呢?如果你仔细观察,你会发现他们基本每天都会进行以下行为:看似莫名其妙的发呆、时不时的傻笑、以及与另一种叫做产品狗的生物撕逼。当然,他们偶尔也对着屏幕写一些多数人不能理解的英文符号,被称之为代码。
这可能在直觉上违反了很多人对于程序猿这种生物的印象,难道他们不是应该每天都在对着键盘狂敲不止么?其实还真不是,生产代码只是程序猿每天所花费时间的小部分,他们每天大多数时间可能用于思考为什么会有这么多奇怪的需求、理解这些奇怪的需求、以及为这些需求设计代码结构。当然,还有最最重要的,也是最花时间的,调试(debug)。
对于大多数程序来讲,改正错误通常是比较快的,但是找到错误在哪儿却通常都是噩梦一场。相信猿类们或者是与这种猿类一起生活过的其他生物们都会有这种经历——改错5分钟,找错2小时(甚至更长时间,比如通宵一晚上)。而且最头疼的是,当你修好了一个错误,总会有另一个错误出现,而且肯定要很久以后这只虫才会冒出来,那时又要重复一遍上述过程。

单元测试的意义

所以,有什么办法可以尽量让猿类避免陷入无穷无尽地找虫子的过程?单元测试是一种很好的手段。

单元测试是bug侦测器

良好的单元测试是强大的bug侦测器,能够大大缩减查找bug所需要的时间。因为修改了代码引入了新的bug,执行单元测试时会立刻出现错误。由于修改前的代码是可以正确运行的,那么错误就一定出在最近修改的这部分代码中,而刚刚修改的代码我们记忆犹新,并且分量也很小,所以很轻松就能找到错误。以前需要2小时才能找到的错误,现在只需要5分钟。

单元测试可以提高代码质量

这可能会让一些人困惑,测试与代码质量有什么关系呢?单元测试是你开发的功能的第一个用户。只有在使用代码时你才会发现代码的缺点。如果你的代码难以测试,那么它通常也难以使用。单元测试可以使你发现程序结构上问题,并在发布前优化。

单元测试可以提高开发速度

这又是一个听上去违反直觉的结论,但事实确实如此。难道编写更多的测试代码不会耗费时间么?当然会,但是编写测试所花费的时间绝对能得到超值的回报,不仅是在项目质量上,在进度上也是如此。频繁地进行单元测试可以让我们更早地发现问题所在,从而节省大量的调试时间,相比于花费一个晚上的睡眠时间找到一两个隐藏很深的bug,花费一点时间编写单元测试真是太值得了。而且从团队角度考虑,你提交的代码中的bug可能影响的并不只是你一个人,还会导致团队中的很多人都在一起找bug。什么,你说你写的程序从来没有bug?好吧,那我只好献上我的膝盖了(别扯了,是人写的程序就会有bug。什么,你说你不是人?那好吧...也许你真得是一只猿类)。

单元测试可以让我们自信地重构

如果没有单元测试,那么重构几乎是不可能完成的任务。因为你不知道你修改的哪行代码会导致整个项目不能运行。敏捷方法论的流行推动了迭代式开发的发展,而敏捷方法论的核心技术就是重构。因为敏捷方法更提倡垂直编写代码来生成一个有效的用例,而不是水平地编写代码来一层一层地提供服务。当你为一个独立的用例或者功能设计编写代码时,你的设计可能是符合这个特性的,但很可能就不符合下一个特性了。为了对所有特性都保持一致的设计,敏捷方法论提倡通过重构来根据需求调整代码。但是如何保证重构不损坏现有代码呢?答案就是单元测试。

少许测试就能获得惊人的收益

很多人都听过这么一句话:“任何测试都不能证明一个程序没有bug”。事实确实如此,但是这并不能成为不测试的理由,也并不能掩盖测试的优点。很多项目的截止日期比较紧,开发人员编写太多测试代码会影响项目的进度,但是少写胜过不写,对核心模块少许的单元测试就能获得惊人的收益。

避免过度测试

其实这不是单元测试的意义(或者说是优点?),而是很多新手同学会犯的错误。就像很多刚学设计模式的同学到处应用设计模式一样,很多刚学会单元测试的同学们喜欢追求100%的测试覆盖率。尽量多的测试当然不是坏事,但当测试数量达到一定程度后,继续增加测试带来的收益提升就会逐渐降低,如果试图编写太多的测试,你可能会因为工作量太大而气馁,并且会影响交付的进度。正确的做法是测试项目的核心模块和容易出错的边界情况。

所以我们需要单元测试

单元测试能让你尽早地发现bug,提升你的开发速度,提高你的代码质量,把你从无穷无尽的调试过程中解放出来,还能让你找到女朋友(因为你有更多的时间去约会)。总之,能让人过上更幸福的生活。那么还有什么理由不去写单元测试呢?

如何向领导推荐单元测试

其实我一直觉得推广单元测试的使用,甚至是强制规定代码的单元测试覆盖率应该是领导来推动的。因为编写单元测试是对项目有利无害的事情,公司的领导应该很喜欢这种对项目的质量和进度都有推进作用的行为。而且程序猿可以在写出难以理解、难以测试、饱含bug的代码库,然后拿了年终奖后拍拍屁股走人,但是项目后续还是需要有人维护的,腐败变质的代码总有一天会让团队付出惨痛的代价(就像击鼓传花,总会传到某个负责维护的人的时候项目的代码彻底不能维护了,于是这个人就背了所有人的锅)。不过如果你所在的公司或者部门没有写单元测试的习惯或规定,也不要紧,你可以向你的领导去推荐。
单元测试有这么多优点,通常来讲,开发经验更加丰富的领导很容易就能明白培养大家编写单元测试的习惯是多么有益(比如我向我的领导大力推荐单元测试时,我的领导就表示很支持,并向我投以了一个令人深思的微笑)。但如果你的领导是一个不懂装懂并且固执己见的老顽固,你可以面露微笑并向他竖起右手中指(千万别这么做!我是开玩笑的,这样很不礼貌,并且可能导致不可预料的后果。如果很不幸的,你已经这么做了,我也不会负责的)。你可以考虑离开这个部门或者这家公司,一个连单元测试都不写的技术团队,也不愿对技术人员和项目负责,并且领导还是个213,还是去刷刷题,准备迎接下一份工作吧。

如何编写单元测试

你以为我会在这里写一些单元测试的技巧?不不不,关于如何编写单元测试可以写一本书了(可能不止一本,我就知道很多关于单元测试和TDD方面的优秀书籍)。我的意思是,网上关于如何编写单元测试的博客已经足够多了(也许我以后也会写一篇),并且有那么多优秀的书籍,当我们了解了单元测试的优点以后,去学习如何编写单元测试就是很自然并且容易的事了。

参考

  1. 《重构 改善既有代码的设计》
  2. 《JUnit实战》(第二版)
上一篇下一篇

猜你喜欢

热点阅读