• 2009-11-15

    勿以善小而不为

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/51441828.html

    我要不要做单元测试呢?这是一个我被许多人问了许多遍的问题,通常,这个问题会出现在讨论TDD的时候,在提问者眼中:

    • 一眼就能看明白,不值得测
    • 单元测试粒度太细
    • 单元测试要写好多,耽误工作量
    • 单元测试不稳定
    • 人员能力有限,写不好单元测试

    正是因为这样的原因,在他们看来,系统测试也许是一个更好的选择。我不否认系统测试的重要性,但是,单元测试才是他们最应该做好的。

    程序员和程序员之间的差异很大程度上是由开发习惯决定的。Kent Beck曾自我评价,“我不是什么伟大的程序员,我只是一个有着很多好习惯的程序员”。单元测试就是一个好习惯。它等于要开发人员在编码的时候就要验证代码的正确性,而不是向后拖。软件开发最基本的一条规律是,越往后做,代价越大。正确性总要验证,那当然是越早验证越好。

    如果你做过单元测试,你就会发现,一旦开始考虑验证,很多之前不曾考虑过的问题就会浮出水面,比如,一些边界条件。单元测试给了我们一个更仔细的关注质量的机会。虽然我们不能说经过单元测试的代码就是100%的完美,但是,我们至少给出了力所能及的验证。而事实上,一旦到更高层面的验证,比如系统测试,比如测试人员的测试,这些所谓的细枝末节是很难覆盖到的。而这些地方又恰恰是很多开发人员认为简单的,不值得测的地方。一旦遗漏,就会成为产品的缺陷,随时可能爆发。

    有人曾给过我们这样一个数据,他们的产品中有15%的bug源自像变量赋值这样非常简单的错误。从这个数据可以看出,很多人还做好自以为很简单的事。程序员有自信是好事,但前提是要有自信的本事。单元测试给了开发人员一个一步一个脚印,踏踏实实走路的机会。当每个构造快都经过验证的之后,把它们组合在一起,我们只要验证他们之间组合就好了。这样的做法,每一步心里都是有底的。而现在的很多开发给人的感觉是在撞大运。

    时至今日,还有很多程序员把开发完成理解成“编码完成”。行百里者半九十,这句话就是给这样的程序员预备的。他们以为自己代码写到90%的时候,其实,后面还有一大半的验证工作等着他们。这些程序员只不过在用有另外一个名字——比如集成——的时间去做他们份内的工作,而某些愚笨的老板居然认为这是天经地义的,所以,他们会压缩编码时间,给后面的验证留下更长的时间,于是,开发人员的时间更紧张了,他们更倾向于前期少验证,一个恶性循环就此形成。

    对于很多人来说,单元测试有问题,但实际上,真正有问题的是代码。为什么测试不好做,因为代码的耦合太大了。为什么单元测试不稳定,因为设计不稳定。谈到这里,我得承认一点,想把这一切都做好,人是关键。不是所有人都能拆解好代码的,但这里真正的问题是,不是所有人都有意识去拆解代码的,那些代码里面的垃圾就是从这里产生的。很多自以为是建设者的人,实际上,是添乱的。

    或许你会说,有很多高手都认为单元测试不是必要的,确实如此,但你光看见贼吃肉了,那些高手个人能力超强,基础扎实,思维缜密,先跟人家比这些东西吧!对于软件开发人员来说,单元测试就是基本功,通过它,可以让人在很多方面得到很多锻炼。先把基本功打扎实再琢磨别的吧!

    分享到:

    历史上的今天:

    聊聊早起 2012-11-15
    引用地址:

    评论

  • 我时常不太愿意写单元测试的是因为:
    *当我频繁重构/调整代码时,单元测试也要相应更新。

    好比注释一样,注释也要随程序更新而更新,单元测试也是——这是我不太喜欢单元测试的原因。
    回复Jerry说:
    注释和代码不一样,因为注释不更新,你发现不了,而测试不更新,一跑就是失败了。正是基于这样的原因,测试的修改相对来说,要容易得多,所以,我也不认为是个多大的问题。

    再有,每次修改代码都要调整测试,也是给了我们另外一个提示,是不是测试写得不好,与代码有耦合,比如,Mock太多。
    2009-11-16 21:49:37
  • 同感啊,很怀念以前写的一个测试脚本,每天上班前就自动跑一次,到上班的时候再看看,总会把搞破坏的家伙揪出来。