每个方法要进行多少次测试?
理论上和高度不切实际的最大值是N-Path复杂度(假设测试全部通过代码涵盖了不同的方式;)。最小为一!。也就是说,按照公共方法,他不测试实现细节,仅测试类的外部行为(返回值和调用其他对象)。
您引用:
*并且用自己的测试方法(以1-1关系)测试每种方法的想法将是可笑的。*
然后问:
因此,如果为每个方法创建测试都是“可笑的”,那么您如何/何时选择编写测试的目的?
但是我认为您在这里误解了作者:
具有这个想法one test method
每one method in the class to test
就是作者所说的“可笑”。
(至少对我来说)不是关于“更少”,而是关于“更多”
因此,让我重新表达一下我对他的理解:
而且,用“ 一个方法”(它自己的测试方法以1-1的关系)测试每种方法的想法将是可笑的。
要再次引用您的报价:
当您意识到这完全是指定行为而不是编写测试时,您的观点就会改变。
练习TDD时,您不会认为:
我有一个方法calculateX($a, $b);
,它需要一个测试testCalculcateX
来测试关于该方法的所有内容。
TDD告诉您的是考虑您的代码应该做的事情:
我需要计算两个值中的较大者(第一个测试用例!),但是如果$ a小于零,则应该产生一个错误(第二个测试用例!),如果$ b小于零,则应....(第三个测试用例!),依此类推。
您要测试行为,而不只是测试没有上下文的单个方法。
这样,您将获得一个测试套件,其中包含代码文档,并真正说明了预期的功能,甚至可能是原因:)
您如何决定为哪个代码创建单元测试?
那么,存储库中或生产附近任何地方的所有内容都需要测试。我认为您的引言的作者不会不同意我在上面所做的陈述。
如果您没有测试,那么更改代码将变得更加困难(更昂贵),特别是如果不是您进行更改。
TDD是一种确保您对所有内容都进行测试的方法,但是只要您编写测试就可以了。通常在同一天编写它们会有所帮助,因为您以后不打算这样做,对吗?:)
对评论的回应:
大量的方法无法在特定的上下文中进行测试,因为它们依赖于或依赖于其他方法
这些方法可以调用三件事:
其他类的公共方法
我们可以模拟其他类,因此我们在那里定义了状态。我们可以控制上下文,因此那不是问题。
*相同的受保护或私有方法*
通常,任何不属于类的公共API的内容都不会直接进行测试。
您想测试行为而不是实现,并且如果一个类完成了所有工作,则它是在一个大型公共方法中或在许多较小的受保护方法中被称为实现的。您希望能够在不影响测试的情况下更改那些受保护的方法。因为如果您的代码更改更改行为,则测试将中断!那就是您的测试所要达到的目的,以告诉您什么时候中断某事:)
同一类上的公共方法
那不是经常发生吗?如果在以下示例中确实如此,则有几种方法可以解决此问题:
$stuff = new Stuff();
$stuff->setBla(12);
$stuff->setFoo(14);
$stuff->execute();
setter存在并且不属于execute方法签名的一部分是另一个主题;)
我们可以在此处测试的是,当我们设置错误的值时,execute是否会崩溃。setBla
当您传递一个字符串可以进行单独测试时,这将引发异常,但是如果我们要测试这两个允许的值(12和14)不能同时起作用(无论出于何种原因),那就不是一个测试用例。
如果您想要一个“好的”测试套件,则可以在php中添加一个@covers Stuff::execute
注释,以确保仅为此方法生成代码覆盖率,而其他仅用于设置的内容则需要分别进行测试(再次,如果你想要那个)。
因此,重点是:也许您需要先创建一些周围的环境,但是您应该能够编写有意义的测试用例,这些用例通常仅跨越一个或两个真实函数(此处不包括设置者)。其余的可以被以太模拟,或者先进行测试然后再依赖(请参阅参考资料@depends
)
*注:这个问题是从SO迁移过来的,最初是关于PHP / PHPUnit的,这就是为什么示例代码和引用来自php世界,我认为这也适用于其他语言,因为phpunit与其他xUnit并没有太大区别测试框架。