【问题标题】:Designing a robust unit test - testing the same logic in several different ways?设计一个健壮的单元测试——以几种不同的方式测试相同的逻辑?
【发布时间】:2010-09-30 20:50:54
【问题描述】:

在单元测试设计中,很容易陷入实际上只是调用你的实现逻辑的陷阱。

例如,如果测试一个整数数组,该数组应该都比另一个高两个(2、4、6、8 等),那么从方法中获取返回值并断言该模式是否真的足够是这样吗?

我错过了什么吗?通过以多种方式测试相同的期望,似乎需要使单个单元测试方法更加健壮。所以上面的期望可以通过检查两个的增加来断言,而且下一个数字可以被 2 整除。或者这只是多余的逻辑?

简而言之,单元测试应该以多种方式测试一个期望吗?例如,如果我想测试我的裤子是否合身,我会/可以测量长度,将它放在我的腿旁边并查看比较等。这是单元测试所需的逻辑吗?

谢谢

【问题讨论】:

  • 所以上面的期望可以通过检查 2 的增加来断言,而且下一个数字可以被 2 整除。或者这只是冗余逻辑? 那是冗余的。并且可能是错误的 - 如果规范说“再多两个”,那么 5 7 是正确的。但是 7 不能被 2 整除(均匀,yadda)

标签: unit-testing testing junit


【解决方案1】:

您的单元测试应该检查您的所有假设。无论您是在 1 次测试还是多次测试中都这样做是个人喜好。

在您上面提到的示例中,您有两个不同的假设:(1) 每个值应该增加 2。(2) 所有值应该是偶数。

应该 (-8,-6,-4,-2) 通过/失败吗?

请记住,确保您的代码在应该失败的时候失败同样重要,如果不是更重要的话,那么确保它在应该失败的时候通过。

【讨论】:

  • 您是否在 1 次测试或多次测试中这样做是个人喜好。我不同意。测试应该尽可能小,尽可能简单,具体命名,并且只测试一件事。
  • @Tony Ennis:我同意你的观点,但不会发动一场圣战 :-)
【解决方案2】:

如果您断言您的数组包含 2,4,6,8 - 那么您的测试逻辑可能有缺陷,因为如果您只返回一个包含这些元素的数组,而不是 6,8,那么您的测试将通过,10,12。您需要测试计算是否正确。因此,在这种特殊情况下,您需要使用多个数组对其进行测试。

我发现确保测试失败,然后让测试通过,本着 TDD 的真正精神,有助于找出正确的测试是什么...

【讨论】:

    【解决方案3】:

    您正在测试的数组必须以某种逻辑生成。测试此逻辑以确保生成的数组始终满足您的要求不是更好吗?

    【讨论】:

      【解决方案4】:

      例如,如果测试一个数组 应该都高两个的整数 比另一个(2、4、6、8 等),是 真的足以得到回报 方法中的值并断言 是这种模式吗?

      也许您需要多考虑一下如何使用该函数。它会与非常大的数字一起使用吗?如果是这样,您可能想尝试一些非常大的测试。它会与负数一起使用吗?

      我错过了什么吗?看起来确实 像单个单元测试方法需要 通过测试变得更加健壮 在几个方面相同的期望。所以 可以断言上述期望 通过检查两个的增加是 正在发生,但下一个数字是 能被 2 整除。或者这只是 冗余逻辑?冗余逻辑?

      嗯...好吧 1,3,5,9 会通过 assertEachValueIncrementsByTwo 测试,但不会通过 assertValuesDivisibleByTwo 测试。它们能被 2 整除有关系吗?如果是这样,那么你真的应该测试一下。如果不是,那么这是一个毫无意义的冗余测试。

      您应该尝试为您的方法找到 1 个以上的测试,但为了进行更多测试而进行的冗余测试对您没有帮助。在不需要的情况下添加 assertValuesDivisibleByTwo 测试只会让后来尝试修改代码的开发人员感到困惑。

      如果您想不出更多测试,请尝试编写一个随机输入函数,该函数将在您每次运行测试时生成 100 个随机测试数组。当您只检查一两个输入集时,您会惊讶于有多少错误在雷达下逃脱。

      【讨论】:

        【解决方案5】:

        我建议进行多次测试。如果您需要更改行为,您希望尽可能少地更改测试。这也使得更容易找到问题所在。如果你真的破坏了实现并得到 [1,3,4,5] 你的一个测试将会失败,但是当你实际上有两个不同的问题时,你只会在你测试的第一件事上失败。

        尝试命名您的测试。如果您不能用一个明确的方法名称说明您要测试的内容,请拆分测试。

        testEntriesStepByTwo
        
        testEntriesAllEven
        

        也不要忘记边缘情况。空列表可能会通过“每个条目比前一个条目多 2 个”和“所有条目都是偶数”测试,但应该这样吗?

        【讨论】:

          猜你喜欢
          • 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
          相关资源
          最近更新 更多