【问题标题】:Testing things that should be the same both ways测试两种方式都应该相同的东西
【发布时间】:2009-11-11 16:29:17
【问题描述】:

例如 Equals 方法。 a 应该等于 bb 应该等于 a。您是否说可以在一个测试用例中使用两个断言来检查这一点,如下所示:

[Test]
public void Equals_TwoEqualObjects_ReturnsTrue()
{
    var a = new Something();
    var b = new Something();

    Assert.That(a.Equals(b), Is.True);
    Assert.That(b.Equals(a), Is.True);
}

或者你认为这应该在两个单独的测试中完成,这样你就不会在测试中有两个断言?

我认为在这种情况下有两个断言可能会更干净,因为我不确定我会如何称呼这两个单独的测试,而且我有点认为哪一个断言破坏了测试。但无论如何,我很想知道其他人对此有何看法,因为我是这个领域的新手 :)

【问题讨论】:

  • 此类方法的其他示例可能是添加两个数字、两个范围的交集等。
  • 我会使用 Assert.Equals 而不是您冗长的语法。我想这就是我使用 xUnit.net 的原因:P
  • 第二个断言需要什么?如果第一个条件为真,则第二个条件也为真,如果对象不相等,情况也是如此。
  • @shahkalpesh:取决于Something.Equals的实现方式
  • @Ruben:没错。关于冗长的问题:在这种情况下,我实际上可以跳过 Is.True ,它会很短。只是想非常清楚:p

标签: unit-testing tdd nunit


【解决方案1】:

我认为让他们参加一次测试绝对没问题。

“每个测试一个断言”的想法对我来说更像是教条,而不是任何有用的东西。务实地进行测试。

是的,每次测试测试一项功能 - 但不要将自己限制在一个断言上。

【讨论】:

  • 我在没有 cmets 解释原因的情况下“撤消”-1s。这使海报获得了 8 分。 Said Horse 的观点是,您需要考虑上下文,而不是像“每个测试一个断言”这样的“最佳实践”阻止您思考。
  • @Ruben -- 我认为你应该只投票你认为有帮助的东西,而不是根据其他人的投票模式投票。
  • @tvanfosson:是像我这样的人把马带到了今天的位置,所以:P 我在得分为 -1 时投了票。评论和+1的目的是让选民解释-1。可悲的是,这还没有发生。我认为“没有教条”的信息很好,而“没关系……”的信息很糟糕。这对我来说是零。但通常不是-1。但我想我的帖子是这么说的。但你是对的 - 投票模式已经被破坏了,我没有出于元原因添加投票。
【解决方案2】:

我要说的是,您必须将两个测试放在一个地方。一个对象等于另一个对象而另一个对象等于另一个对象是不够的。这是相同的两个对象同时彼此相等。

在两个断言的情况下,您的测试意图(测试 equals 是可交换的)要清楚得多。

【讨论】:

    【解决方案3】:

    视情况而定。

    如果您正在做一些复杂的事情,其中​​具有可交换性是一个关键功能并且不是一件容易的事,那么让测试足够细化以反映这一点是有道理的 - 它可以让您更快地隔离问题。

    在很多情况下,这将是矫枉过正。测试必须有重点。

    这么说并不意味着你应该在尽可能多的断言中硬生生——这在另一个方向上太过分了。

    底线是没有也不应该是绝对的规则。但总的一点是保持测试

    • 有助于隔离问题
    • 有助于记录行为

    【讨论】:

      【解决方案4】:

      我会在两个测试中对它们进行测试,就好像其中一个链接设置不正确一样,您将确切知道是哪一个,记住单元测试测试尽可能小的单元。

      【讨论】:

        【解决方案5】:

        你的两个断言都测试同样的东西。一种类型的一个对象等于同一类型的另一个对象。 Equals 代码没有任何方法可以告诉它正在调用哪些局部变量以及哪些是参数。我认为有一个断言就足够了,该断言表明一种类型的任何对象都等于该类型的任何其他对象。如果这是真的,那么交换性成立。

        【讨论】:

        • @tvanfosson:取决于Something.Equals的实现方式,不是吗?
        • 您将如何实现它,以便您可以选择一种类型的任意元素,并使其与该类型的任何其他任意元素相等,并且无法反转这些选择?
        • 普通的简单类型很难搞砸,但有可能。关键是,如果您正在测试您编写的 Equals 方法的 impl,它需要的属性之一是可交换的。因此您可能想在测试中涵盖这一点?
        • 如果发生这种情况,那么在我看来,您选择的不是最简单的东西来通过测试或故意忽略方法的语义。
        • 你最后一点是有道理的。我只是说 Equals 方法是否正确的核心部分是它是可交换的。一般来说,它是否实现这一点是毫无疑问的。如果有任何疑问,可能只是测试 Equals 实现的功能的那个方面。如果这是测试的目的,那么您绝对应该有这两个 Assert.Equal 调用(并且可能将 IsCommutative 放在测试名称中以反映这一事实。或者将两个断言提取到一个断言方法中以使其非常清楚。
        猜你喜欢
        • 2018-03-22
        • 1970-01-01
        • 1970-01-01
        • 2012-07-16
        • 2014-11-02
        • 2020-11-14
        • 1970-01-01
        • 1970-01-01
        • 2018-05-23
        相关资源
        最近更新 更多