【问题标题】:How to apply TDD with complicated function?功能复杂的TDD如何应用?
【发布时间】:2017-07-28 15:02:11
【问题描述】:

Bob 大叔的测试驱动开发的三个规则如下:

  1. 除非是为了通过失败的单元测试,否则您不得编写任何生产代码。

  2. 您不能编写任何超过足以导致失败的单元测试;编译失败就是失败。

  3. 您编写的生产代码不得超过足以通过一个失败的单元测试的数量。

例如,在现实世界中,我的任务是完成一个需要一些复杂算法(例如一些高级数学知识)的方法,如果我应用上述 3 条规则,它将是这样的:

  • 开始编写测试用例 => 运行并看到它失败

  • 编写足以使测试通过的代码行

  • 重构代码

  • 然后重复这个循环。

我的问题是:这种方法在这种情况下是否非常不切实际和分心?

为什么我们不编写第一个测试用例,然后专注于找到解决方案然后实施它,我的意思是看大局,而不是编写足够的代码来通过第一个测试用例?

【问题讨论】:

标签: unit-testing testing tdd


【解决方案1】:

我认为另一个答案很好,但除此之外:如果 一个 方法需要您实现 几个 算法 - 你确定这样的方法尊重 单一责任原则?听起来这种方法做的事情太多了。

所以,当您退后一步看到使用了 3 种算法时 - 这已经告诉我们 每个 算法可能应该进入自己的方法。而且我们的“初始”方法只会调用这些其他方法来完成一些计算。

并且朝着其他方向前进 - 没有任何法律可以阻止您调整 TDD 以满足您的需求。这导致了一种我称之为“自下而上 TDD”的做法。

它是这样的:不是首先为我的一个巨大的方法编写一个测试 - 实际上我会考虑在那个巨大的方法中我需要的不同的部分。所以我只写了第一部分的测试;然后实施。我对所有部分都这样做。随着时间的推移,这些部分得到了增强,也许我在途中将较小的部分合并为更大的部分(这很可能意味着也将多个测试合并为一个更大的测试)。

这种技术可能意味着您可能最终会为您的庞大方法提供一个测试用例 - 但实际上您在构建“大型解决方案”时使用 TDD 来测试小部分。

换句话说:我不是为那个方法的 public 合约编写一个大的功能测试 - 我首先为我知道我需要的小型辅助方法编写测试。最后,这些助手将是 private 方法 - 直接测试它们是没有意义的。但是您可以保留早期测试的那些部分,这些部分在您的大型公共方法的上下文中是有意义的。

长话短说:所有这些技巧都旨在引导您找到自己的方式。鉴于您有足够的经验来动态设计,以这种方式使用 TDD 是可能的(而且实际上很有趣)!

【讨论】:

    【解决方案2】:

    根据我使用 TDD 的经验,执行这些小步骤有一些优势:

    让开发者思考应该如何使用代码

    一个易于理解的方法名称、输入(我将从文件、数组中读取)、输出(将是一个 json、ArrayList)以及每个特定输入的行为(引发异常,什么都不做)。

    测试反馈更精准

    执行小步骤可帮助您专注于如何处理算法中的特定情况。例如,假设一个带有快速排序算法的 TDD:

    def "Given an empty list, when I use quicksort, should raise an exception"()
    def "Given an list of one elements, should return the list itself"()
    def "Given an ordered list of elements, should return the list itself"()
    def "Given an unordered list of elements, should return a copy of ordered list"()
    

    请注意,测试本身应该非常精确且详细地说明您要测试的行为。 一个不太好的测试可能是这样的

    def "Given an list, should give me an ordered list"()
    

    如果上面这个测试失败,是因为没有抛出异常而失败?还是列表已排序但更改了原始列表?

    您的测试代码成为规范

    如果您对算法进行一些广泛的测试代码,您可能会隐藏算法的一些重要细节。您的代码中所有重要的部分都必须有一个编写良好的测试用例。这样做,你最终会得到一个基本上是你的算法规范的测试代码。 如果其他开发人员问你你的算法应该如何工作,只需向他展示测试用例即可。

    一开始我的想法和你一样。感觉就像我们在浪费时间,做这些婴儿步骤似乎很荒谬。但是相信我,你练习得越多,你就越能意识到 TDD 的好处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多