Unit testing TDD和;“诚实”;试验的

Unit testing TDD和;“诚实”;试验的,unit-testing,testing,tdd,atdd,Unit Testing,Testing,Tdd,Atdd,在做TDD时,我关心测试的“诚实性”。TDD是 写红色测试 编写足够的代码使其成为绿色 重构并让测试保持绿色 到目前为止还不错。下面是一个应用上述原理的示例,在教程和现实生活中已经遇到过此类示例: 我想检查当前用户的电子邮件是否显示在我的webapp的默认页面上 写一个红色的测试:example@user.com“显示在default_page.html中 编写足够的代码使其成为绿色:硬代码“example@user.com“在默认页面内 通过实现get_current_user()、其他层中的

在做TDD时,我关心测试的“诚实性”。TDD是

  • 写红色测试
  • 编写足够的代码使其成为绿色
  • 重构并让测试保持绿色
  • 到目前为止还不错。下面是一个应用上述原理的示例,在教程和现实生活中已经遇到过此类示例:

    我想检查当前用户的电子邮件是否显示在我的webapp的默认页面上

  • 写一个红色的测试:example@user.com“显示在default_page.html中
  • 编写足够的代码使其成为绿色:硬代码“example@user.com“在默认页面内
  • 通过实现get_current_user()、其他层中的一些代码等进行重构,让测试保持绿色
  • 我对第二步感到“震惊”。这里有点不对劲:测试是绿色的,即使没有任何东西真正起作用。这里有一种测试的味道,这意味着可能在某个时候有人可以在不破坏测试套件的情况下破坏生产代码

    我在这里遗漏了什么?

    你说得对

    第二步。这里有点不对劲

    但这不在方法中。在测试逻辑中。完成所有这些(步骤2)后,确认测试线束工作正常。在不需要任何新代码的情况下,新测试不会错误地通过,并且所需的特性不存在

    我错过了什么


    这一步也应该测试测试本身,以否定的方式:它排除了新测试总是通过的可能性,因此毫无价值。由于预期的原因,新测试也应该失败。至关重要的是,这一步骤增加了开发人员的信心,让他们相信它正在测试正确的东西,并且只在预期的情况下通过测试。

    我想说,您所拥有的只是部分完成。你说:

    我想检查当前用户的电子邮件是否显示在我的webapp的默认页面上

    测试不会在默认页面上检查当前用户的电子邮件地址,而是检查固定的电子邮件地址“example@user.com“在页面中

    为了解决这个问题,您需要提供更多的示例(即使用不同的电子邮件地址进行多个测试),或者在测试设置中随机生成电子邮件地址

    所以我想说,你得到的是类似于这是伪代码的东西:

    Given current user has email address "example@user.com"
    When they visit the default page
    The page should contain the email address "example@user.com"
    
    这是您可以在TDD中编写的第一个测试,您确实可以对其进行硬编码,以避免实现不必要的东西。现在可以添加另一个测试,它将强制您实现正确的行为

    Given current user has email address "example2@user.com"
    When they visit the default page
    The page should contain the email address "example2@user.com"
    
    现在,您必须删除硬编码,因为您无法使用硬编码解决方案同时满足这两个测试。因此,这将迫使您从当前用户处获取实际电子邮件地址并显示此地址

    通常,在测试中以3个示例结束是有意义的。这些不需要是3个单独的测试,您可以使用数据驱动的测试来重用具有不同值的相同测试方法。您没有说明您使用的是什么测试框架,所以我不能给出一个具体的示例


    这种方法在TDD中很常见,称为三角法。

    您关于“没有任何东西在工作”的断言是错误的。如果电子邮件地址为example@user.com. 您不需要最后的重构。您的下一个失败测试可能是在用户有不同电子邮件地址的情况下使其失败。

    您认为将文本硬编码到页面上符合“编写足够的代码使其变为绿色”的条件是什么?当然,它确实有测试测试的好处。@T.J.Crowder,因为不幸的是,这是关于TDD的著名书籍所支持的胡说八道。@OliverCharlesworth:正如我所说,它有测试测试的好处,这是一件非常重要的事情……这是真的:这三个步骤并不包括所有的软件开发。它们只是路标。是的,你可以像描述的那样玩它们,就像你可以玩任何“三步流程”一样。不过,不要这样做,你会没事的。如果您真的担心其他人会这样做,您可以让测试为每次运行随机生成不同的电子邮件地址。@T.J.Crowder我不同意“测试测试”。测试是测试自身和测试中的内容。+ 1,OP正处于过程的中间,并且需要添加更多的测试来确定它们的确切行为,但是……很多书,包括著名的建议不要过度使用三角测量。使用三角剖分重构测试通常更好(并使测试更连贯)。另外,在单元测试中,随机生成用户名并不是一个很好的实践(其中包含“random”一词的任何内容都不应该出现在单元测试中)。尽管如此,关于三角测量,还是有一个很好的答案。不过,我不确定我是否同意测试中的“无随机性”。有时,您只需要一个值,而不需要它是特定的,并且“随机”生成数据可以避免将解决方案编码到测试数据中。如果对随机对象使用相同的种子,则每次都保证相同的测试数据,尽管它是随机生成的。这消除了由于测试数据而导致测试随机失败的担忧。是为提供此类数据而编写的框架。