代码之家  ›  专栏  ›  技术社区  ›  Sruly

YAGNI在编写测试时也适用吗?

  •  13
  • Sruly  · 技术社区  · 17 年前

    我应该提前为我能想到的每个用例编写一个测试,只是为了安全起见,还是应该只在遇到用例时为其编写测试?

    11 回复  |  直到 17 年前
        1
  •  13
  •   tvanfosson    17 年前

    我认为,当你编写一个方法时,你应该测试预期和潜在的错误路径。这并不意味着你应该扩展你的设计来涵盖每一个潜在的用途——把它留到需要的时候,但你应该确保你的测试在面对无效参数或其他条件时定义了预期的行为。

    在这种情况下,我更关心的是,你是否应该编写涵盖意外使用的测试——例如,由于传递null或超出范围的参数而导致的错误——或者重复仅在数据而非功能方面有所不同的测试。在前一种情况下,正如我上面所说的,我会说是的。您的测试将记录您的方法在出现错误时的预期行为。这对使用你的方法的人来说是重要的信息。

    在后一种情况下,我不太能给你一个明确的答案。你当然希望你的测试保持干燥——不要编写一个简单地重复另一个测试的测试,即使它有不同的数据。或者,除非你练习数据的边缘情况,否则你可能不会发现潜在的设计问题。一个简单的例子是一个计算两个整数之和的方法:如果你传递它,会发生什么 maxint 作为两个参数?如果你只有一次测试,那么你可能会错过这种行为。显然,这与前一点有关。只有你能确定什么时候真的需要或不需要测试。

        2
  •  9
  •   Joseph    17 年前

    是的,YAGNI绝对适用于写作测试。

    例如,我不编写测试来检查任何属性。我假设属性以某种方式工作,在我找到一个与常规不同的属性之前,我不会对它们进行测试。

    你应该始终考虑写任何测试的有效性。如果写测试对你没有明显的好处,那么我建议你不要。然而,这显然非常 主观的

    此外,我会编写测试来验证输入吗?当然。不过,我会这么做的 到一定程度 假设你有一个有3个参数的函数,它们是整数,它返回一个double。你打算围绕这个函数编写多少测试。我会在这里使用YAGNI来确定哪些测试会让你获得好成绩 投资回报率 ,这些都是无用的。

        3
  •  4
  •   GalacticCowboy    17 年前

    根据需要编写测试。测试就是代码。预先编写一堆(最初失败的)测试打破了TDD的红色/修复/绿色循环,使识别有效的失败与未编写的代码变得更加困难。

        4
  •  4
  •   ChrisF    17 年前

    1. 您的测试有助于定义此阶段的功能。
        5
  •  3
  •   jAST    17 年前

        6
  •  3
  •   Michael Borgwardt    17 年前

    当然,为你不确定是否会实现的用例编写测试是没有意义的——这对任何人来说都是显而易见的。

    对于你知道会实现的用例,测试用例的回报是递减的,也就是说,当你可以用一半的工作覆盖所有重要和关键的路径时,试图覆盖每一个可能的模糊的极端情况并不是一个有用的目标——当然,假设忽略一个很少发生的错误的成本是可以承受的;在编写航空电子软件时,我当然不会满足于低于100%的代码和分支覆盖率。

        7
  •  3
  •   John Rudy    17 年前

    你可能会在这里得到一些变化,但一般来说,编写测试的目标(对我来说)是确保你的所有代码都能正常运行,没有副作用,以可预测的方式运行,没有缺陷。那么,在我看来,你讨论的只为出现的用例编写测试的方法并没有真正的好处,实际上可能会造成伤害。

    如果您忽略的被测单元的特定用例导致最终软件出现严重缺陷怎么办?在这种情况下,开发测试所花费的时间是否给你带来了虚假的安全感之外的任何东西?

    (郑重声明,这是我使用代码覆盖率来“衡量”测试质量时遇到的问题之一——如果覆盖率低,可能会表明你的测试不够,但如果覆盖率高,不应该用来假设你是坚如磐石的。测试常见情况和边缘情况,然后考虑单元的所有ifs、ands和buts,并对其进行测试。)

    我应该注意到,我的观点可能与这里的许多人不同。我经常发现我正在为多个不同的客户编写库风格的代码,即将在多个项目中重用的代码。因此,我通常不可能肯定地说某些用例根本不会发生。我所能做的最好的事情就是记录它们不是预期的(因此可能需要在之后更新测试),或者——这是我的偏好:)——只是编写测试。我经常发现选项2在日常生活中更宜居,因为当我在新的应用程序Y中重用组件X时,我有了更多的信心。在我看来,信心就是自动化测试的全部意义。

        8
  •  2
  •   David Thornley    17 年前

    你当然应该推迟为你还没有实现的功能编写测试用例。测试应该只针对现有功能或您即将投入的功能编写。

    然而,用例并不等同于功能。你只需要测试你已经确定的有效用例,但可能会发生很多其他事情,你想确保这些输入得到合理的响应(这很可能是一条错误消息)。

    显然,你不会得到所有可能的用例;如果可以的话,就不必担心计算机安全了。你应该至少得到更合理的,当问题出现时,你应该将它们添加到用例中进行测试。

        9
  •  1
  •   Paul Fisher    17 年前

    我认为这里的答案是,就像在很多地方一样,这取决于。如果一个函数呈现的合约声明它执行X,并且我看到它有相关的单元测试等,我倾向于认为它是一个经过良好测试的单元,并以此方式使用它,即使我在其他地方没有完全使用它。如果这种特定的使用模式没有经过测试,那么我可能会感到困惑或难以追踪错误。因此,我认为测试应该涵盖一个单元的所有(或大部分)定义、记录的行为。

    如果您选择以增量方式进行测试,我可能会在文档中添加注释,说明该函数“仅针对[某些类型的输入]进行测试,其他输入的结果未定义”。

        10
  •  0
  •   Carl Manaster    17 年前

        11
  •  0
  •   Billy    17 年前

    如果你在TDD或XP风格下工作,你不会像你说的那样“提前”写任何东西,你会在任何给定的时刻处理一个非常精确的功能,所以你会编写所有必要的测试,以确保这部分功能按你的意愿工作。

    测试代码与“代码”本身类似,你不会为你的应用程序的每个用例提前编写代码,那么你为什么要提前编写测试代码呢?