TDD测试是否应该首先失败?

时间:2009-07-03 15:34:22

标签: language-agnostic tdd

作为this answer评论中的讨论的跟随者,TDD测试是否应该首先失败?

考虑以下示例。如果我正在编写LinkedHashSet的实现和一个测试测试,在插入副本之后,原始版本与插入之前的迭代顺序相同,我可能想要添加一个单独的测试,副本不在设置完毕。

第一次测试将首先失败,然后实施。

问题在于,使第一个测试过程的实现很可能使用不同的集合实现来存储数据,所以就像第二个测试已经通过的副作用一样。

我认为看到测试失败的主要目的是确保测试是一个很好的测试(很多次我写了一个测试,我认为会失败,但没有,因为测试写错了)。但是,如果您确信您所编写的测试确实测试了某些内容,那么必须确保您以后不会破坏该行为并不值得吗?

6 个答案:

答案 0 :(得分:9)

当然它很有价值,因为它是有用的regression test。在我看来,回归测试比测试新开发的代码更重要。

要说他们必须始终首先失败就是采取超越实际的规则。

答案 1 :(得分:6)

是的,TDD测试必须在变为绿色(工作)之前失败。否则你不知道你是否有有效的测试。

答案 2 :(得分:4)

对我而言,TDD更像是一种设计工具,而不是事后的想法。所以没有别的办法,测试会因为没有代码让它通过而失败,只有在我创建测试才能通过之后。

答案 3 :(得分:4)

我认为“先失败”的观点是避免开玩笑说测试有效。如果您有一组测试使用不同的参数检查相同的方法,那么它们中的一个(或多个)可能会从一开始就通过。考虑这个例子:

public String doFoo(int param) {
    //TODO implement me
    return null;
}

测试类似于:

public void testDoFoo_matches() {
    assertEquals("Geoff Hurst", createBar().doFoo(1966));
}

public void testDoFoo_validNoMatch() {
    assertEquals("no match", createBar().doFoo(1));
}

public void testDoFoo_outOfRange() {
    assertEquals(null, createBar().doFoo(-1));
}
public void testDoFoo_tryAgain() {
    assertEquals("try again", createBar().doFoo(0));
}

其中一个测试将通过,但显然其他测试不会,所以你必须正确实现代码才能通过测试集。我认为这是真正的要求。规则的精神是确保在开始黑客攻击之前考虑过预期的结果。

答案 4 :(得分:1)

您实际上要问的是如何测试测试以验证它是否有效,并且它会测试您的意图。

首先让它失败是一个好的选择,但是请注意,即使它在你计划失败时失败并且在你重构代码以使其成功之后成功,那仍然不会意味着你的测试实际测试了你想要的东西......当然你可以写一些其他类的行为,以测试你的测试......但这实际上是一个测试你的原始测试的测试 - 你怎么知道新的测试有效吗? : - )

首先让测试失败是一个好主意,但它仍然不是万无一失。

答案 5 :(得分:0)

恕我直言,首先失败的重要性在于确保您创建的测试没有缺陷。例如,您可以在测试中忘记Assert,并且您可能永远不会知道。

当您进行边界测试时会出现类似的情况,您已经构建了覆盖它的代码,但建议您进行测试。

我认为这不是一个大问题,你的测试不会失败,但你必须确保它确实测试它应该是什么(调试,也许)。