Android单元测试(二):为什么要进行单元测试

发表于:2018-5-23 14:15

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:一笑小先生    来源:简书

  前言
  最近,在网上看到过一个调查,调查的内容是“程序员在项目开发中编写单元测试的情况”。当然,至于调查的结果,我想聪明的你已经可以猜到了。高达 58.3% 的比例,一般情况下不写单元测试,只有偶尔的情况才会写写。16.6% 的程序员从来都不写单元测试。只有很少的一部分程序员才会在自己的代码中进行单元测试,并保证方法测试通过。看到这些,你想到了什么?
  现状
  虽然,这个调查可能会有些片面性,但这也基本反应了国内程序员的开发现状,很少有程序员能够比较认真的去编写单元测试。而且,甚至有的程序员根本就不知道为什么要写单元测试(这一点让我很郁闷)。他们经常会说,公司里不是有测试人员嘛,测试应该是他们要做的事,我们的工作只是开发(这位仁兄肯定没有学过软件工程)。当然,这些并不是偶然的,正如佛经里边说的“因果循环”,有果必有因。那么,到底是什么原因,导致程序员对单元测试这么不感冒呢?
  理由
  那么到底又是什么原因造成程序员不写单元测试呢?
  1、没时间。项目进度太紧张,项目计划里完全没有预留单元测试代码开发的时间;正常代码想搞完时间都很紧张,程序员巴不得把业务代码搞定之后休息、放松一下,单元测试代码再重要,但其开发工作也就自然放在一边了。
  2、没必要。老代码一大片,都堆在那里,身经百战,产品应用那么久,如果有Bug早该发现了,现在写单元测试代码不是浪费时间和金钱嘛。
  3、不必要。代码功能这么简单,逻辑也不复杂,抽时间代码Review就可以了,何必为其专门开发单元测试代码。
  4、工具不足。模块之间依赖重重或者没有依照面向接口的思想开发,导致静态对象满天飞,程序员手里缺少简单易用的测试框架,导致各种业务场景无法模拟,异常场景更是不消讲,单元测试的意义大打折扣,程序员没有意愿付出时间开发单元测试代码。
  5、程序员自身能力不足。对项目组可用的单元测试工具使用不熟练,开发单元测试代码时间效率低下,或者需要花费很多时间解决单元测试代码中的问题,或者单元测试代码运行结果不稳定,无法起到质量看护的效果,这样也会导致程序员没有兴趣和意愿在项目进行过程中开发单元测试代码。
  6、需求不稳定,导致代码变动大,已有的单元测试代码需要投入时间和精力维护,这样也会导致程序员没有兴趣和意愿来写单元测试。
  7、老代码结构混乱,可测试性比较低,开发单元测试代码的代价比较高,而这些代码已应用了相当的时间,为了写单元测试代码而做针对性的修改,意义不大,投入和产出不成比例。
  。。。。。。
  很显然,这几种原因归根结底,无外乎就是不了解单元测试,自认为很聪明,自己懒不想去测试,对项目的时间、进度把控不好。
  认识单元测试的好处
  前面讲了为什么不写单元测试的原因,接下来讲讲用了单元测试这种写代码的方式以后,给我带来什么样的好处。
  更好的设计
  当你为自己的代码写单元测试的时候,尤其是采用TDD的方式,你会很自觉地把每个类写的比较小,功能单一,这是软件设计里面很重要的SRP原则。此外,你能把每个功能职责分配的很清楚,而不是把一堆代码都塞到一个类里面(比如Activity)。你会不自觉的更偏向于采用组合,而不是继承的方式去写代码。这些都是很好的一些代码实践。
  至于为什么TDD能够改善代码的设计,网上有很多的文章去分析和论证这个结论。我看到比较印象深刻的一句话是(具体在哪看的搜不出来了):当你TDD的时候,你是从一开始,就从一个代码的使用者,或者说维护者的角度,去写你的代码。这样写出来的代码,自然会有更好的设计。
  节约时间
  对于安卓开发来说,一遍一遍的运行app,再执行相应的用户操作,看界面是否显示正确的结果,通过这种方式来测试自己的新代码、重构是否是正确的,这是非常浪费时间的一件事情,而且效果还不好。有了单元测试,我现在开发过程中几乎已经不用把app运行起来了,速度相对来说快多了。
  此外,因为单元测试能帮我减少bug,从而也减少了调试bug,fix bug的时间。一个切身感受是,自从开始写单元测试以后,我启动AndroidStudio的debugger的次数明显减少了。这也是单元测试节约时间的地方。
  当然,这个结论也是自我感觉的结果。写单元测试需要时间,这也是不能否认的事情,至于有单元测试是否真的更快,快了多少,我没有具体的统计数据,所以很难给出一个确切的答案。
  这里需要重点说一下的是,你为新代码写的单元测试,不仅仅是能在目前你这次写新代码的时候起了作用,它的作用更体现在以后重构代码的时候,你可以很快速,很安全的进行重构。这点往往大家会忽略,所以会觉得在单元测试上花费的时间“不值得”。
  更少的bug,或者说更快的发现bug
  测试能够使我们尽量早的发现程序的bug.
  一个bug被隐藏的时间的越长,修复这个bug的代价就越大。在《快速软件开发》一书中已引用了大量的研究数据。指出:最后才修改一个bug的代价是在bug产生时修改它的代价的10倍。
  为所有的类编写测试,可以让我们很容易的修改bug。当接到一个bug报告后,我们总是先修改测试代码,然后修改实现代码,使测试成功。这样不会因为修改一个问题而造成新问题的产生。
  良好的单元测试策略给我们增强了对程序的信心,减少了bug的产生及bug的潜伏期。降低修改bug的代价。单元测试不会是项目开发周期的某一个生命周期,它贯穿于项目的整个生命周期,是一个非常重要的日常开发活动。
  更快的结果反馈
  有单元测试的帮助,我可以写完一个独立的代码单元,就立刻验证它的正确性,这跟需要完成所有代码再把app运行起来手动测试相比,是一个更快的反馈循环,能更快的发现代码是否正确。
  增加自信
  测试常常是程序员十分厌倦的一个活动。测试能给我们带来什么?了解这些是非常重要的,测试不可能保证一个程序是完全正确的,但是测试却可以增强我们对程序完整的信心,测试可以让我们相信程序做了我么期望它做的事情。测试能够使我们尽早的发现程序的 bug 和不足,也能让你变成一个更好的程序员。
  没有时间写单元测试?
  前面大概讲了讲我为什么要写单元测试,以及单元测试给我带来的好处,这些其实如果大家去google “why unit testing”,估计会得到类似的答案,然而依然会有很多人不写单元测试。如果问为什么的话,那么得到最多的回答,估计是:没有时间。
  那么,写单元测试真的需要很多时间吗?为什么多数真正写过单元测试的人会说,写单元测试可以节约时间呢?在这里,首先要承认两点。。。
  单元测试,的确是一门需要学习的技术。不仅需要学习,而且你要学习的东西还真不少,你要学习JUnit的使用,你要学习Mokito的使用,Robolectric的使用,依赖注入的概念和使用等等等待。此外,在刚开始的时候,你的确也会遇到很多坑,现有代码的坑,Android的坑,Robolectric的坑等等。这个在安卓开发这边显得更是如此,因为Android开发环境是公认的最不利用写单元测试的环境之一。你需要花一些时间去学习如何处理,或者是绕过这些坑。
  在一个现有的,没有单元测试的项目里面加入单元测试,会需要一段时间的调整。一个有单元测试的项目,跟一个没有单元测试的项目相比,结构会有比较大的不同。因此刚开始,你会发现各种不顺利的情况,你需要去调整各部分的代码,让他们变的容易测试,这也是比较花时间的地方。
  这种调整值得吗?我认为是值得的,因为容易测试的项目,往往意味着更灵活,更具备扩展性,这个前面已经提到过了。所以本身这件事情就是一件值得做的事情,更何况,测试本身又是一件非常有价值的事情。
  然而等跨过了这两道坎,单元测试还需要花很多时间吗?根据我自己的经验,我觉得其实不是这样的,因为等你熟悉了如何写单元测试以后,要对一个类、一个接口写单元测试,是很容易的一件事情。如果你发现一个类不好测,往往是因为这个类的设计是有问题的。此外,你可以慢慢的搭建自己的一套测试框架,简化一些常用的繁琐的写法,让写单元测试变得更简便快捷。再加上前面讲述的原因,总体来说,我觉得写单元测试非但不会需要跟多时间,反而会节约时间。
  小结
  这篇文章简单讲述了,为什么要写单元测试。其实,单元测试的必要性,看看那个知名的程序员必看书单就知道了。在前20本中,所有5本讲述“如何写出更好的代码”的书,无一例外都强调单元测试的必要性。
  Code Complete
  The Pragmatic Programmer
  Refactoring: Improving the Design of Existing Code
  Clean Code: A Handbook of Agile Software
  Craftsmanship by Robert C. Martin
  Working Effectively with Legacy Code by Michael C. Feathers
  希望这篇文章,能让你多一点学习和实践单元测试的决心,因为这真的是非常值得拥有的一项技能,只是刚开始的时候,需要多一点点时间而已。



上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号