【问题标题】:Test-driven Development: Writing tests for private / protected variables测试驱动开发:为私有/受保护变量编写测试
【发布时间】:2011-03-04 05:02:10
【问题描述】:

我正在学习 TDD,我有一个关于私有/受保护变量的问题。我的问题是:如果我要测试的函数在私有变量上运行,我应该如何测试它?

这是我正在使用的示例:

我有一个名为Table 的类,其中包含一个名为internalRepresentation 的实例变量,它是一个二维数组。我想创建一个名为multiplyValuesByN 的函数,它将二维数组中的所有值乘以参数n

所以我为它编写了测试(在 Python 中):

def test_multiplyValuesByN (self):  
    t = Table(3, 3) # 3x3 table, filled with 0's
    t.set(0, 0, 4) # Set value at position (0,0) to 4
    t.multiplyValuesByN(3)

    assertEqual(t.internalRepresentation, [[12, 0, 0], [0, 0, 0], [0, 0, 0]])

现在,如果我将 internalRepresentation 设为私有或受保护,则此测试将不起作用。我应该如何编写测试,使其不依赖于internalRepresentation,但在调用multiplyValuesByN 后仍然测试它看起来是否正确?

【问题讨论】:

    标签: unit-testing variables tdd private protected


    【解决方案1】:

    其他人已经发布了很好的答案,但恕我直言,没有强调一件事:设计方面(尽管 Peter Tillemans 提到了它)。所以我对此添加一点解释。

    在进行 TDD 时,您正在有效地测试 API 的设计以及实现。如果你发现一个方法调用的结果很难或不可能从外部看到,这几乎总是表明你的类接口设计得不好。如果为您的课程编写测试很困难,那么在现实生活中通常也很难使用它 - 您的单元测试实际上是您课程的第一个客户。因此,如果您发现测试用例难以使用您的类接口,您应该考虑返回并重新设计您的 API 以使其更易于使用(如果可能,不要损害封装)。

    【讨论】:

      【解决方案2】:

      如果是内部的,那么在课堂之外是没有人的事情,包括测试。

      在 TDD 中,您正在设计类的 API,而未来的客户也只能看到类的可观察行为。

      我知道这说起来容易做起来难。

      在测试中,您经常会看到重复出现的模式:设置 - 操作 - 检查(- 拆卸)

      设置阶段负责将对象置于前置条件状态。

      检查阶段应通过类的可观察行为来验证后置条件。如果它永远不会出现,那么存储不可见状态是没有意义的。

      【讨论】:

      • ...也称为 Arrange-Act-Assert(但没有与 Teardown 匹配的头韵 - 猜这是一件好事,它没有被太多使用!)
      • 是的,这就是我把它放在括号中的原因。这是有时需要但不适合理论的实际事物之一。我喜欢 3-A 头韵。以前没听说过,谢谢!
      【解决方案3】:

      不要测试私有变量/状态。您的测试应确认被测单元符合其规范,并且该规范由其接口确定。所以你的测试应该根据你的测试单元的输入来编写,并验证输出是否符合你的期望。

      您希望能够更改被测单元的实现(例如,出于效率原因),并确认它按预期工作。所以在这种情况下检查私有状态会造成困难。

      【讨论】:

        【解决方案4】:

        您不应依赖对象的内部表示。这就是为什么它被标记为私有或受保护的原因。考虑调用 t.multiplyValuesByN(3) 时对 t 进行了哪些可观察到的更改。然后,测试你能观察到的东西。

        def test_multiplyValuesByN (self):  
            t = Table(3, 3) # 3x3 table, filled with 0's
            t.set(0, 0, 4) # Set value at position (0,0) to 4
            t.multiplyValuesByN(3)
        
            assertEqual(t.get(0,0), 12)
        

        【讨论】:

          猜你喜欢
          • 2020-09-06
          • 2019-04-04
          • 1970-01-01
          • 1970-01-01
          • 2022-11-18
          • 1970-01-01
          • 2022-01-08
          • 2018-03-18
          • 1970-01-01
          相关资源
          最近更新 更多