“单元测试要做多细?”[转载]
原文出处:酷壳 - CoolShell.cn 作者:陈皓
这篇文章主要来源是StackOverflow上的一个回答——“How deep are your unit tests?”。一个有13.8K的分的人(John Nolan)问了个关于TDD的问题,他说——
“TDD需要花时间写测试,而我们一般多少会写一些代码,而第一个测试是测试我的构造函数有没有把这个类的变量都设置对了,这会不会太过分了?那么,我们写单元测试的这个单元的粒度到底是什么样的?并且,是不是我们的测试测试得多了点?”
八卦一个答案
StackOverflow上,这个问题的答案是这样的——
“I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence (I suspect this level of confidence is high compared to industry standards, but that could just be hubris). If I don’t typically make a kind of mistake (like setting the wrong variables in a constructor), I don’t test for it. I do tend to make sense of test errors, so I’m extra careful when I have logic with complicated conditionals. When coding on a team, I modify my strategy to carefully test code that we, collectively, tend to get wrong.”
老板为我的代码付报酬,而不是测试,所以,我对此的价值观是——测试越少越好,少到你对你的代码质量达到了某种自信(我怀疑这种的自信标准备要高于业内的标准,但这种自信也可能是种自大)。如果我的编码生涯中不会犯这种典型的错误(如:在构造函数中设了个错误的值),那我就不会测试它。我倾向于去做那些有意义的错误测试,所以,我对一些比较复杂的条件逻辑会异常地小心。当在一个团队中,我会非常小心的测试那些会让团队容易出错的代码。
Different people will have different testing strategies based on this philosophy, but that seems reasonable to me given the immature state of understanding of how tests can best fit into the inner loop of coding. Ten or twenty years from now we’ll likely have a more universal theory of which tests to write, which tests not to write, and how to tell the difference. In the meantime, experimentation seems in order.”
不同的人有不同的测试方式,在如今这种不成熟的时期,这些能够适应于内部编码的测试方式对我来说都比较合理。也许从今后十年或二十年,我们会对“什么要的测试需要写,什么样的不需要”达成更广泛的共识,并且我们可以知道这两者的区别。与此同时,各种实践都在各自发生中。
这个问题并不新鲜,但是这个回答对TDD似乎有一种否定,最亮的是这个问题是由Kent Beck,Kent是XP和TDD的创造者,是敏捷开发实践方法的奠基人。以致于还有人调侃到——
The world does not think that Kent Beck would say this! There are legions of developers dutifully pursuing 100% coverage because they think it is what Kent Beck would do! I have told many that you said, in your XP book, that you don’t always adhere to Test First religiously. But I’m surprised too.
只是要地球人都不会觉得Kent Beck会这么说啊!我们有大堆忠实程序员在追求着100%的代码测试覆盖率,因为这些程序员觉得Kent Beck也会这么!我告诉过很多人,你在你的XP的书里说过,你并不总是支持“宗教信仰式的Test First”,但是今天这么说,我还是很惊讶!
后面还有一些不人同意Kent, 我一下子从这个事中想到了《fight club》里的那个精神分裂者创建了一个连自己都反对的地下组织。呵呵。
其它答案
八卦完了,我们还是来认认真真地看看这个问题中其它的其它答案。
第二个答案:值得借鉴
- 开发过程中,单元测试应该来测试那些可能会出错的地方,或是那些边界情况。
- 维护过程中,单元测试应该跟着我们的bug report来走,每一个bug都应该有个UT。于是程序员就会对自己的代码变更有两个自信,bug 被 fixed,相同的bug不会再次出现。
第三个答案:给敏捷咨师看的答案
这个答案在说,我们只注意到了TDD中的T,而忽略了第一个D,就是Driven…… bla bla bla… 又这扯这些空洞的东西了,国内的各种不学无术的敏捷咨询师最好这一口了。
第四个答案:致那些什么都要测试的人
如果我们需要测试一个像 int square(int x)
这样的开根函数,我们需要40亿个测试(每个数都要测试)。
事实上这种情况可能还更糟糕,如果有这样一个方法 void setX(int newX)
不会更改其它的成员变量,如:obj.z, Obj.y,那么,你是不是还要去测试一下别的变量没有被改变?
因为,在国内也有很多很多人在问这类的问题——单元测试究竟要做多细?