我的神呀,测试驱动开发真的有效!

我们经常听到人们宣扬说,在开发软件时写测试代码(单元测试,功能测试等)能有效的减少产品中的bug。如何验证这样的言论?通常,这些人都是已经在使用驱动测试开发(TDD)或行为驱动开发(BDD),而且,他们所在的公司在诞生第一天起就有着很强的测试文化。然而,如何能测量不写测试程序造成的影响?如何能验证实践TDD能真正的减少bug的存在?我们能否在一段时间里停止写测试程序,看看这对软件缺陷数有多大的影响?这方法看起来不太现实。

这篇文章里,我将通过分析当前我工作中的真实数据来回答这个问题。以前我们的系统没有测试代码,可一旦开始进行测试驱动开发,我就成为了这种开发方法的强力倡导者。

测试驱动开发前的背景情况

我做Web开发已经有10年了,从2009年起就开始耳闻驱动测试开发(TDD)。从那时开始我就打算要多学学这方面的知识。我在当时的公司里已经干了两年,现在已经是2012年,在这个公司总共工作了5年,从后3年开始实施测试驱动开发方法。

这个过程非常有趣,因为如今我可以浏览我们的bug跟踪系统,汇总这段时间的缺陷统计数据,看看TDD对我们的程序代码质量有多大的影响。

简单的说一下我们的软件技术构成:我开发基于PHP和Javascript的系统UI部分。我是UI部分的主要开发人员,这就是说,如果UI上有bug,我基本上要对此负责。UI跟后台的C++服务交互,这服务运行在Oracle数据库上,通过PLSQL代码处理数据。

UI部分的PHP代码是唯一实施了测试驱动开发的地方。我们的Javascript代码没有测试程序。遗憾的是,公司里的程序员都没有测试驱动开发的实践经验。系统其它层面的代码都没有实施单元测试或功能性测试(公司有专门的QA团队在开发完成之后进行测试)。

这使得我们的统计分析数据看起来非常的明显。我可以看到,随着时间的推移,我们的整个产品和UI模块的缺陷数字的变化。这使得我有办法来回答最初的问题,这个问题在此可以用这样的问题复述:使用测试驱动开发能使我负责的UI模块的缺陷数下降吗?

测试驱动开发真的有效吗?

下面这个图表是由我们的bug跟踪系统生成的。它向我们展示了UI部分的bug和整个产品的bug的对比比率。

我们可以从中看出一些有趣的事情:

  • 首先,我可以回答这个问题:在UI中发现的bug的数量(下面绿颜色的)减少了50%(起初UI部分相关的bug数量占整个产品的35%,如今它已经降到了15%)。
  • 在历史遗留的程序库上实施测试驱动开发并不会很快的显现出效果。我于2009年第三季度开始TDD。你可以看到,到了2010年第三季度时bug数才开始下降,而到了2011年第三季度开始大幅度下降。将近用来2年的时间实现了50%的降低。
  • 图表上显示,在2010年第二季度和2011年第二季度时,数据上下跳动。看一下我们产品的发布历程,这应该归结于这段时间系统里增加了严重依赖于Javascript的第三方地图API功能。我之前也说过,我们并没有写Javascript上的测试代码。这也证实了不写测试代码会导致更多的bug。

下一步的计划?

之前我说过,我只是在PHP代码上实施了测试驱动开发。观察如今产生的bug,我注意到它们通常可以归为这样两类:

  • Javascript代码中的bug(这些是没有自动化测试程序的)
  • 系统集成时产生的bug(例如,独立的PHP组件通过了单元测试,但组合起来运行时却出了问题)

这很自然的将我引入了下一步的测试探险:我要在Javascript代码里加入测试套件代码,并最终加入集成测试套件代码。

今年整个夏天我都在做这项工作。对于Javascript代码,开发了基于Jasmine BDD框架的测试套件。对于端对端的测试,我使用Cucumber。在这两种情况中,我使用Selenium Web Driver在真实的浏览器中运行测试代码,或胡乱的使用强大的Phantom.js

我们即将开始下一个开发周期,我期望通过这些新的措施,我们能开发出更有质量的软件。我希望明年还能写出这样的一篇文章来分析这些测试开发工具的效果。很有可能它们会进一步的降低我们的bug数量。

还有,把这些数据分享给我的同事,这让一些开发人员也开始相信测试驱动开发的好处。我们产品中另外一些服务上的开发人员对TDD表现出了兴趣,准备研究如何在他们的程序库上实施测试驱动开发。观察他们的在实践中能获得什么样的成果将会是一件有趣的事情。

结束语

你呢?测试驱动开发(TDD)和行为驱动开发(BDD)是如何影响你们的代码质量的?你是否也有类似的统计数据可以分享?请在下面的评论里写出来。

[英文原文:OMG, Test Driven Development Actually Works! ]
分享这篇文章:

13 Responses to 我的神呀,测试驱动开发真的有效!

  1. David says:

    在上一个项目中,我开始写测试代码。bug数明显少了很多,我很兴奋的向其他同事介绍时,响应却很平静…

  2. 3o,, says:

    书呆子。
    如果你之前一个项目没用测试驱动,后一个用了,然后bug明显减少了,那是因为,你在前一个项目赚了经验值,你升级了,于是bug就少了,而不是采用TDD的方法。
    唉,如果你开发几乎相同的项目,bug居然不会减少,那只能说明你是头猪。

  3. 3o,, says:

    如果一个人愿意采用tdd,说明这个人要比一般的要勤奋些,显然,这要求敲更多的代码。这就好比你去大悲寺修行,每天大早起来劈柴挑水做功课,搞了几个月发现身体越来越好了,越来越精神了,你以为这是功德的力量,信仰的力量,其实是因为这些宗教仪式性质的东西,让你的生活更规律了,所以身体好了。

    别被那些宗教性质的表象迷惑了真实。还是看看人家是怎么说的吧。
    http://coolshell.cn/articles/8209.html
    如果做同样的项目,你不采用tdd结果bug又涨回去了,那只能说明你像卖拐里的范伟一样二了。

    • David says:

      tdd会花费更多的时间,关于tdd的争论一直再继续,有的程序员会说你是否想更早的拿到产品。我的观点是单元测试确实能为我的代码提供质量保证,公司有两个类似的项目,两个组开发,我所在的组写了测试代码,而另外一个组没有,我明显的看到,他们的bug比我们的多得多。所以我并不是被宗教性质迷惑了,只是真是感受而已,当然我承认产品的开发效率很重要的,所以单元的粒度划分需要经验积累的。

  4. ppretender says:

    TDD确实能降低bug数量,并且在后期做bug fix时能提供有效的回归测试。我觉得程序员应该对TDD持积极态度,项目组再根据实际的情况做安排。

    • 3o,, says:

      这个世界需要认真对待的事情太多了,人人都想要提升工作绩效的方法,但这个东西显然不是,一个东西这么久了还是没成为业界普遍接受的说明一个问题,就像中医吹得那么神,现在还是有好多人治不好病。
      因为鼓吹的人总是倾向于忽略一件事物的另一面。

      你是消灭了bug,但是你花费了更长的时间,更多的人工,得到的结果是一样的。老板不会因此付给你更多的钱。所以tdd做了什么?把bug换一种形式表现出来罢了。

      所以不要总是强调tdd改善了什么,看看它的另一面,在一些人获得成功的同时,有更多的人采用同样的方法依然失败了。就好像不会因为有人发明了一种助记法,就拯救了不爱读书的孩子,发明了一款健康减肥药,胖子就绝迹了一样。人家早就说了,没有银弹。

      这就是为什么一般人对这玩意反响很平淡的原因,这只是一种方法,并没本质的改善什么东西,那么为什么一定要认真对待它,个人癖好而已。

  5. Dlad says:

    比率……
    为什么不能是由于php端代码量突然增多,bug激增,所以TDD部分的bug比率下降了呢?

  6. Dlad says:

    tdd如同面向对象,是一种大方法论
    为降低复杂度,降低雇用成本,使年薪5K的coder也能做年薪20k的任务,而设计
    滥觞于工业化的管理需要,毫无优雅可言。
    “通过测试”的代码常常伴随着无尽的代码债务,反正我绝对不想和接手这种代码的人互换位置。

  7. Yonghang Jiang says:

    我只知道有TDD覆盖的情况下重构代码起来真是豪气冲天啊

    不用TDD,你得用更长的时间才能保证你的代码没有bug,而且会很累,而且即使很累,用了很长时间,你还是不能保证你的代码没有bug。看不能运行的代码的日子在考完C语言二级考试后就该结束了。

  8. Kingsly 对这篇文章的反应是赞一个

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据