如果TDD是针对单位的,那么测试如何首先意外通过(作为错误)?

时间:2018-03-19 06:31:09

标签: unit-testing testing tdd

我读过一篇关于TDD的研究,其中一个常见问题(开发人员之间的调查)表示他们并没有真正让测试失败。然后作者说:

  

如果新测试没有失败,程序员会收到一个指示   生产代码没有按照他们的想法和代码工作   修订可能是必要的。可能发生的另一个问题是   程序员无法确定测试通过的原因;没有   确保新代码实际上对它负责。考试   从一开始就实施可能是错误的。

我想知道,TDD测试怎么能首先通过(因为他们提到的生产代码),如果它在单位级别?我的意思是,如果所有人都被嘲笑(存根......),它应该始终是孤立的,因此永远不能真正先通过。

2 个答案:

答案 0 :(得分:3)

假设您有两个课程CalculatorFormatter

Calculator根据输入计算一些值,Formatter将值转换为字符串进行显示。

您已在FormatterTest中进行了一些测试:

  • test_value_is_formatted_as_number
  • test_empty_is_formatted_as_NA

现在您实施新功能Show zero values as N/A

在TDD之后,您将向Formatter test_zero_is_formatted_as_NA添加一项测试,该测试首先检查此项并且您希望它失败:

def test_zero_is_formatted_as_NA(self):
    assert formatter.format(0) == 'N/A' 

但碰巧它通过了,原因是Formatter已经这样做但Calculator返回浮动零,其精度有限。

def format(value):
    if value == 0 or value is None:
        return 'N/A'
    return format_as_string(value)

所以测试通过但是如果你写另一个测试它会失败:

def test_very_small_number_is_treated_as_zero_and_formatted_as_NA(self):
    assert formatter.format(0.00000001) == 'N/A'

答案 1 :(得分:0)

通常情况下,您描述的情况很容易发生在某些事情已经实施但系统的另一部分(使用此实现的部分)以某种方式限制它,例如通过更强的先决条件。然后,如果你不熟悉代码,你可能会遇到这样的惊喜。

考虑这个例子:

public string ShowScoreEvaluation(byte points)
{
    switch(points)
     case 3:
        return "You are good!";
     case 2:
        return "Not bad!";
     case 1:
        return "Quite bad";
     case 0:
        return "You suck!"

}

//caller code
if (Points>0)
  ShowScoreEvaluation(points)

在上面的代码中,当Points = 0时,调用代码不期望调用该方法。也许在该方法的实现过程中,即使对于points = 0的情况,程序员也只是把它放在那里(作为一个笑话或占位符)。

现在想象一下,你加入这个项目并得到一个新的请求“当玩家有0分时,显示一个令人鼓舞的消息blabla”。 你用Points = 0编写一个单元测试,并期望一个长度> 0的字符串...并且它没有失败,尽管你会期望它。