代码之家  ›  专栏  ›  技术社区  ›  Matt H

行为与基于状态的测试

  •  5
  • Matt H  · 技术社区  · 14 年前

    我知道这个问题是一场宗教战争的一部分,但我有以下情况: 我有一个物体, Responder 对对象调用方法 Updater 响应不同的事件。我最近以这种方式分离了测试:基于状态的测试 更新程序 方法本身以及 应答器 这就是它。也就是说,我嘲笑 更新程序 应答器 测试,只是为了确保调用它。

    我是否仍要测试应该在 应答器 测试而不是嘲笑 更新程序 ?我喜欢我所做的,因为它需要更少的设置,并且似乎更好地隔离测试。然而,这似乎与 应答器 更新程序 . 那太脆了吗?这是一个简单的例子。

    2 回复  |  直到 13 年前
        1
  •  9
  •   Grzenio    14 年前

    如果我正确理解了你的问题,你至少需要两个级别的测试:

    1. 单元测试,其中您试图只测试一个类并模拟所有依赖项(因此在您的情况下,更新程序需要在这里模拟)。这些测试可以帮助您开发代码(尤其是在使用TDD的情况下),确保类的行为与设计的一致,甚至记录这个类的行为方式。几乎每个类都应该有单元测试。但是,正如您注意到的,即使您有100%的测试覆盖率,您也不能保证您的程序能够正常工作甚至启动!

    2. 验收、集成和端到端测试——这些测试包括整个应用程序或大型模块,并测试所有东西都能一起工作。一般来说,在这个级别上不使用模拟(不过,根据上下文的不同,您可能会截取整个模块/Web服务)。这些测试不需要测试每一个实现细节(也不应该),因为这是由单元测试完成的。他们确保所有的东西都正确连接在一起并一起工作。在您的情况下,您不会嘲笑这里的更新程序。

    所以,总而言之,我认为您确实需要同时进行这两项工作,才能正确地测试您的应用程序。

        2
  •  0
  •   Rodi    13 年前

    我想这取决于你想测试什么/如何测试。

    如果在更新程序类中没有任何依赖项,那么除了在调用被测试方法后测试它的状态之外,没有其他方法。如果存在某种依赖关系,您可以测试它的行为,以确定它应该做什么(在其他类上调用其他方法)

    另一种方法也适用于响应程序类。你可以测试它的状态,或者像刚才那样测试它的行为。测试它的状态时,您可能会使用更新程序的实际实现,而不是模拟它,或者在只做最少的地方使用存根。

    当主要测试行为和模拟很多东西时,更需要进行验收(回归/集成/端到端)测试来备份单元测试,就像grzenio提到的那样。(他似乎是个“模仿者”(行为)测试者)

    在大多数情况下进行基于状态的测试时,您会使用更真实的实现及其交互,而备份这些实现的需要就不那么重要了。但这绝不是完全丢弃它们的方法,只是您的测试中已经有了一些回归/集成。

    我认为你不应该把测试分成太多的部分,因为这可能会使事情更容易陷入裂缝之中。

    免责声明:我不是TDD专家,我不主张一个比另一个。关于经典vs行为的好信息可以在网上找到。马丁·福勒在这个问题上有一个很好的起点: Mocks Aren't Stubs

    我目前正在阅读不断增长的面向对象软件,在测试的指导下,我倾向于模仿围墙的一面。但我认为两边都有一个小的灰色区域。