BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

如何控制单元测试的粒度?

| 作者 崔康 关注 1 他的粉丝 发布于 2012年9月8日. 估计阅读时间: 6 分钟 | CNUTCon 了解国内外一线大厂50+智能运维最新实践案例。

单元测试的粒度问题一直是软件开发社区面临的现实问题,最近,陈皓针对StackOverflow上的老问题做了总结,并发表了自己的看法,读者在随后的评论中也进行了讨论。

John Nolan在《How deep are your unit tests?》中问道:

TDD需要花时间写测试,而我们一般多少会写一些代码,而第一个测试是测试我的构造函数有没有把这个类的变量都设置对了,这会不会太过分了?那么,我们写单元测试的这个单元的粒度到底是什么样的?并且,是不是我们的测试测试得多了点?

最佳答案是:

老板为我的代码付报酬,而不是测试,所以,我对此的价值观是——测试越少越好,少到你对你的代码质量达到了某种自信(我觉得这种的自信标准应该要高于业内的标准,当然,这种自信也可能是种自大)。如果我的编码生涯中不会犯这种典型的错误(如:在构造函数中设了个错误的值),那我就不会测试它。我倾向于去对那些有意义的错误做测试,所以,我对一些比较复杂的条件逻辑会异常地小心。当在一个团队中,我会非常小心的测试那些会让团队容易出错的代码。

最让人意外的是,这个答案是由XP和TDD的创造者Kent Beck给出的! 难怪有人评论说:

只是要地球人都不会觉得Kent Beck会这么说啊!我们有大堆程序员在忠实的追求着100%的代码测试覆盖率,因为这些程序员觉得Kent Beck也会这么干!我告诉过很多人,你在你的XP的书里说过,你并不总是支持“宗教信仰式的Test First”,但是今天Kent这么说,我还是很惊讶!

陈皓则是非常同意Kent的回答:“怎么合适怎么搞,爱怎么测试就怎么测试,只要自己和团队有信心就可以了。没有必要就一定要写测试,一定要测试先行。”

其他排名靠前的答案包括:

Dominic Rodger

为可能会出错的地方和边界情况编写单元测试。另外,单元测试应该跟着缺陷报告走,在修补缺陷之前编写好单元测试。开发人员就会对代码充满自信:一是bug已经修补,二是bug不会重现。

kitofr

关于TDD最大的误解之一就是第一个字母——测试(T)。这也是BDD出现的原因。因为大家没有真正理解第一个D(驱动)的重要性。我们总是倾向于对测试关注更多,而对设计的驱动关注太少。我想这是一个模糊的回答,但是你应该考虑如何驱动你的代码,而不是测试什么,这是覆盖率工具该做的事情。设计是一个很大而且问题更多的问题。

最后,陈皓表达了自己的观点:

  • 目前的国内教育模式让我们习惯于标准答案,习惯于教条,从而不会思考!敏捷开发中的若干东西似乎都成了软件开发中对某种标准答案的教条,实在是悲哀!
  • 软件开发是一种脑力劳动,是一种知识密集型的工作,就像艺术作品一样,创作过程和成品是没有标准答案的。
  • 软件的质量不是测试出来的,而是设计和维护出来的。就像工匠们在一点一点地雕琢他们的作品一样。

许多读者在原文的评论中表达了自己的看法

  • 对于要做多细,我的经验就是:当我不在的时候,如果同事打电话说有Bug,询问是否会是我的问题,而我可以很自信的回答No的时候,就可以啦! 所以最享受的就是大家加班,而我在放心玩乐的时刻。这让我想起了一件事情,有位同行朋友学车,一开始总想让师傅告诉他,需要“打点方向”的时候到底是多少度? 需要“加点油”的时候到底是加到每小时多少公里? 后来知道了,没人会告诉你,你得自己Do!
  • 其实我觉得在现今大型企业的团队中, 开发人员的职责就是开发和保证代码正确的实现 至于测试则基本是交给测试的人员来做,而测试人员又拿着测试的工资,他们不会考虑开发人员的水平,而是循规蹈矩的去完成整个测试流程。
  • 关于StackOverflow上出现的大量排斥TDD的观点,我尝试这样来解释:占主流群体的底层程序员在没有监督的情况下缺乏责任心只求应付工作......到了工作岗位上也是如此,领导在不在大不一样。总结下来就是,大多数人在没有监督的情况下容易慵懒应付。这应该是人的天性。后来工厂出现的流水线,应该就是对付这种情况的。把工作流程标准化、流水线化,让整个流水线上的人都没机会偷懒。我想这也是TDD的目标之一。如果没有足够的测试用例,你怎么确认某个模块是功能完整的无明显缺陷的?如果原作者离职了,后来的维护者修改了先前的代码,又如何保证不影响以前的功能?要知道,你修改一个新bug,很可能会把以前的多个旧bug放出来,有经验的开发者应该明白我说的什么意思。于是软件越来越难于维护,维护者也越来越排斥修改代码,一潭死水无人敢碰,软件提前寿终正寝。我最终的结论就是,TDD要由项目管理者推动实施,而不能征求下面程序员的意见,——他们虽然人数众多,但就像面对老师的学生一样,总是要求玩耍而不是学习,这对项目本身是无益的。
  • 说白了还是看你怎么用,TDD也只不过是个方法罢了,工具而已,又不是思想或者本质之类的。我个人开发就很不TDD,即使需要写测试也是针对公开的接口或者某些特定的调用去做测试程序,这样的好处是达到测试代码的目的,同时又有了一个测试程序。缺点是这个测试程序不带好集成到发布过程。但换言之,好的程序员写的代码自然质量较高,差的程序员有没有单元测试一样差,甚至于无法保证差的程序员写的测试单元没有BUG,如果有BUG那不是更悲剧?

InfoQ的读者朋友对此有何自己的见解? 

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

粒度很难把握。 by 东喆 王

按需编写测试粒度,这个说起来容易,做起来有些麻烦,毕竟不是每个程序员都有那个水平,很多时候会导致只为了应付工作堆积测试,有的和没有一样。到浪费时间了。

感觉还是有点泛泛了 by 姚 志翔

自了解TDD开始,我一直没搞清楚到底这个测试要做到什么程度?在具体实施也只是凭感觉摸着走!

说得很好 by 钟 健鑫

我也认为TDD是一种保证软件质量的方法而已,TDD什么时候用、用多少这个确实是需要自己把握的,这个就跟系统设计一样!
如果为了测试用例,会耗费大量的时间,那还不如直接手工测试(比如只是为那些很大的系统模块中添加一些耦合度相对较高的功能时)
但是如果是一个新的功能模块,而且逻辑较复杂,为了验证功能和设计的正确性 我认为应该为它写TDD并在今后维护此模块时同时维护
测试用例,这样能够更高效的保证此模块的质量!

Kent Beck说的那个“少”,对大部分项目来说,其实是非常多 by 张 辉

Kent Beck:“少到你对你的代码质量达到了某种自信(我觉得这种的自信标准应该要高于业内的标准,当然,这种自信也可能是种自大)”。
“某种自信”其实是很不容易做到的。个人认为,整个team都明确认为完全不需要UnitTest的地方,那就是真的不需要写的;整个team都认为必须需要UnitTest,那就是一定要写的;对于某些代码是否需要UnitTest,自己在纠结,团队中也有不同意见,那么也是一定需要写的,因为还有没有达到“某种自信”,直到随着时间的推移,大家对类似的问题已经明确了共识,有了“某种自信”,那就不用写了。

这就是所谓的“经验” by Chan Jackei

1.经验。不仅仅是我做过什么什么,做了多少多少次,多少多少年,更重要的是在一次次重复的过程中,发生了思维的改变。直白一些说就是在做的过程中不断的思考、学习、改进。否则就只是重复了N次,而并没有对等的经验。——这个问题在一直以来的面试中经常遇到,很多声称有4年经验的 tester,其实只是重复了很多工作,而经验只能相当于2年。
2.情境。区分从新手到专家各个不同等级的重要标志,直白的说,就是一个人对当前所需要解决的问题认识的是否准确。这个不太好量化,牵扯到一个“怎么知道自己认识的是否准确”的问题,所谓的“决策失误”之类的,就是这么个事情。作者的一个观点是“新手通常乐观而无畏,而专家就谨慎的多”。

《程序员的思维修炼》里面讲了很多这个。www.cnblogs.com/jackei/archive/2012/06/01/25294...

粒度上要知止,测试代码也是需要维护的,我的经验是止于接口 by King Jon

个人开始真正写单元测试,始于代码重构,重构的正是代码的业务底层核心模块,被众多的外部模块调用,每一点修改都有可能动一发而系全身,不得不小心应对,如履薄冰。根据用例写好测试,先跑通原有代码,记录相应结果,再重构代码,跑同样的测试,看输出结果是否一致。测试粒度基本集中在对外提供的接口上,并尽量的完善用例,如此也能达到很好测试覆盖率。另外测试代码也需要维护的,粒度太细,就琐碎不好维护了。而基于接口的话,接口变,测试跟着更新就好了。
我对自己的要求的是没经过自己测试的代码坚决不提交给QA、PI等测试,一怕麻烦,二则是尊重对方。试想如果我的程序出现了低级的错误,空指针、参数异常等,测试人员反馈回来,我再自己调试修改,重启服务更新,多少时间去了。测试人员也有自己的喜好,他们肯定不乐意老测些低级的bug,而更喜欢测出深沉次的bug(比如业务逻辑上的)。所以对我来说写单元测试是一种习惯,责任感使然。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

6 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT