【问题标题】:Unit Testing-- fundamental goal?单元测试——基本目标?
【发布时间】:2010-05-04 01:51:41
【问题描述】:

昨晚,我和我的同事对我们的 PHP/MySQL 应用程序中的单元测试存在一些分歧。我们中有一半人认为,当在一个类中对一个函数进行单元测试时,您应该模拟该类及其父类之外的所有内容。我们另一半认为,你也不应该嘲笑任何直接依赖于类的东西。

具体的例子是我们的日志机制,它通过一个静态的 Logging 类发生,我们在整个应用程序的不同位置有许多 Logging::log() 调用。我们前半部分说应该伪造(模拟)Logging 机制,因为它将在 Logging 单元测试中进行测试。我们后半部分认为我们应该在我们的单元测试中包含原始的 Logging 类,这样如果我们对我们的日志接口进行更改,我们将能够查看它是否会由于失败而在应用程序的其他部分产生问题更新通话界面。

所以我想基本问题是——单元测试是用来测试封闭环境中单个单元的功能,还是显示在更大环境中更改单个单元的后果?如果是其中之一,您如何完成另一个?

【问题讨论】:

  • +1 这是一个很好的问题,因为它暴露了一些我认为很多人对单元测试感到困惑的东西。

标签: php unit-testing phpunit


【解决方案1】:

您和您的同事偶然发现了单元测试和集成测试之间的区别。嘲笑一切都会为前者完成;后者不会模拟依赖项。

当然,您在哪里划定粒度线也有点主观 - 但在单元测试的最详细级别,您不应该担心每个测试的特定主题之外的任何事情。

【讨论】:

  • 有时,当您决定测试某些东西并且是 平台 的一部分时,即使在单元测试中也可以决定使用它。例如,您不会伪造标准库,或者可能不是您信任能够正常工作的框架。如果你能负担得起这样的信任,它可能会节省一些代码行。
  • 是的,非常正确 - 通常模拟是为作为项目的一部分开发的组件保留的,只是当前不是正在测试的东西。
  • +1 - 同意单元测试是独立执行的,应该覆盖 100% 的代码。集成测试是一致执行的,覆盖率不需要那么高——你测试的是交互而不是功能。 enhance-php.com/Content/About-Unit-Testing
【解决方案2】:

单元测试就像测试电子设备中的单个组件。

如果您想测试吉他放大器中的单个晶体管,您无需插入吉他、调高音量并检查发出的声音。那将是愚蠢的。要检查晶体管,请将设备连接到该晶体管的引线并仅测量其输入和输出。

在某些时候,您确实会测试整个东西(吉他会发出噪音等),但这与测试单个晶体管是不同的。

【讨论】:

    【解决方案3】:

    这些词给出了答案的一些提示:

    unit 表示 1:你正在尝试测试一件事。当这不是测试的主要焦点时,您可以模拟日志框架之类的依赖项。被测试的单元如何与其依赖项交互通常是测试用例的一部分,而模拟使这变得更容易。

    集成意味着不止一件事结合在一起:你试图将不止一件事结合在一起作为一个整体的测试。模拟的作用较小,但它仍然可以用于模拟难以在测试场景中设置的依赖项。

    我想说的是,在单元测试中不模拟日志系统以查看更改是否会破坏任何内容的论点非常薄弱。如果日志系统中有任何问题,那么应该通过日志系统的单元测试失败来捕获。

    保持单元测试简单、清晰和专注是一个很好的经验法则。 Yuu 在扩大测试范围时需要这种简单的基石。集成测试很快就会变得复杂,尤其是在使用它们作为缺少单元测试的替代品时——就像“远距离测试”,离组件越远,测试和诊断故障就越困难。通过单元测试测试远程依赖就像一个人试图在房间的另一边使用钓鱼竿操作电视遥控器。

    【讨论】:

      【解决方案4】:

      @David,我看到你的单元测试正在做它应该做的工作。

      您正在反思软件的设计。

      从您提出有关封闭环境与开放环境的问题的方式来看,这让我相信您即将为您的代码回答基于状态与行为单元测试的问题。

      对于何时使用真实对象或模拟进行单元测试没有硬性规定。 仅指导原则! 使用真正的Logging 对象进行单元测试的问题在于,该对象的测试不仅在记录器的单元测试中,而且在对象的单元测试中使用记录器。

      因此,如果您有 20 个使用记录器的对象,并且当您更改记录器接口时,将至少有 21 个失败的测试。这在重构时可能会很痛苦。但另一方面,如果您在 20 个对象单元测试中不使用记录器类并且您更改记录器接口,那么您只有一个失败的测试和其他 20 个变为绿色的单元测试,即使它们在生产中会失败。

      我真正能给你的唯一见解是你没有正确的抽象。您可能想查找SOLID。这些应该是指导原则。

      请记住,无论何时出现问题,例如您提出的问题,都是代码为您提供反馈。注意那个反馈。它会在以后为您节省很多痛苦。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-31
        • 1970-01-01
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 2018-01-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多