【问题标题】:Unit testing with C/C++: Lessons, what to remember?使用 C/C++ 进行单元测试:经验教训,要记住什么?
【发布时间】:2010-09-18 07:12:46
【问题描述】:

使用 C/C++ 进行单元测试: 你教那些以前没有做过单元测试或者来自 Java/Junit 的人什么?

从您的角度来看,可以节省大量时间或压力的最重要的课程/要记住/练习的事情是什么(尤其是在 C/C++ 方面)?

【问题讨论】:

    标签: c++ unit-testing tdd


    【解决方案1】:
    1. 单元测试必须在每次签入时自动运行(或者,编写然后忘记的单元测试不是单元测试)。
    2. 在修复错误之前,编写一个单元测试来公开它(它应该会失败)。然后修复错误并在测试变为绿色时欢欣鼓舞。
    3. 牺牲一点类的“美”来简化测试是可以的(例如提供不应该真正公开的公共方法,但有助于您的测试/模拟)。

    【讨论】:

    • 我不同意 1. 所有的 UT 都应该在夜间构建期间自动运行,因为它们通常需要很多时间。在每次签入之前,您应该只为您的模块运行 UT。
    • 3.也是错误的 - 让 UT 班级成为朋友,他们会看到一切
    • m_pGladiator:“根据定义,如果运行时间超过 1/10 秒,则 UT 不是 UT。”,从有效使用旧代码中解释)。因此,可以在每次提交时自动运行它。
    • 我也不同意 3。您可以在不牺牲其设计的情况下检查类的内部,例如在测试类中声明一个仅存在于 UT 中的友元观察者类。
    【解决方案2】:

    读这个……无论如何你都会……

    【讨论】:

      【解决方案3】:

      我反对所有这些关于自动授予测试类友谊的建议...

      就我个人而言,我更喜欢关注以下内容,以便访问我需要测试的类的内部:

      1. 依赖于公共接口 尽可能上课;有时这意味着稍微扩展公共接口以便于测试。不要过多地反对这些扩展,但也不要让它们过多地推动您的设计......
      2. 考虑添加一个监控接口 也可以由“真实”代码使用 作为测试代码,以启用监控 被测代码。 (我仍然惊讶于这是设计过程中非常好的一部分)。
      3. 考虑通过“受保护的接口”为派生类提供对类的某些部分的访问,并派生相关类的“可测试”版本,然后可以对其进行检测和测试。

      总之,我更喜欢在测试点中看到设计,而不是与测试类建立全面的友谊。当然,前者比后者更难做,但恕我直言,会产生更好的代码和更好的测试。

      【讨论】:

      • @Len - 好点。我通常会非常努力地不必为了测试而使用公共方法。当测试某些代码变得困难时,您的测试会告诉您您的设计存在问题。你真的,真的想要更好的设计。花点时间,它会变得更容易。
      • 听你的代码,闻你的代码 - 友谊只是为了测试臭!
      【解决方案4】:

      我想改写 ripper234 并添加更多规则:

      1. 每个模块(通常是 DLL 项目)都应该有单独的 UT 项目。所有 UT 类都应该是它们访问私有方法/成员所需的所有 DLL 类的朋友。
      2. 如果您想更换模块 - 首先更换 UT。在签入前确保 DLL 及其 UT 编译、链接和 UT 在没有崩溃和故障的情况下运行。在每次签入之前无需为所有模块运行所有 UT - 这是浪费时间。
      3. 所有 UT 应与所有 DLL 一起在夜间构建中自动重建。所有 UT 和模块都应在构建期间进行编译和链接。
      4. 夜间构建成功后应自动运行所有 UT,并汇总结果。
      5. 应将包含所有 UT 结果的摘要发布给开发人员,如果出现任何故障或崩溃,应尽快予以纠正。

      【讨论】:

        【解决方案5】:

        在处理没有测试的遗留代码库的情况下,您很可能会(正如我必须)从使用单元测试框架进行实现的功能测试开始。不要惊慌——您的代码是如此相互关联,以至于可能无法编写适当的单元测试。也不要自满——一旦功能测试到位,您需要重构以便真正的单元测试成为可能。你的代码会更好!

        【讨论】:

          【解决方案6】:

          最重要的一课:有考试总比没有考试好。

          【讨论】:

          • 除非测试被破坏,当然,在这种情况下,你是在虚假的前提下运送的。
          • 事实上,我认为一个班级的 1 次测试比 100 次测试更重要。第一次测试总是最难的,尤其是遗留代码,因为它迫使你打破类周围的依赖关系,以便你可以首先对其进行测试。
          【解决方案7】:

          一个单元测试用例应该只测试一件事。

          与 C# 和 Java 相比,我在 C/C++ 中更经常看到单元测试用例测试整个工作流程。

          也许是因为大多数 C/C++ xUnit 框架需要几个步骤来注册一个测试用例,所以在添加新功能时只在现有测试用例中添加几行的诱惑更大。

          【讨论】:

          • 我同意,但是,我也希望看到测试对象 A 插入到对象 B 等的“单元测试”,而不是只测试对象 A 的模拟测试对象 B。我意识到这些更像是“集成测试”,但它们也非常有用。
          • 也没有人禁止您进行集成测试。你只是不应该称它们为单元测试——甚至不是“单元测试”。将它们称为集成测试,不要将它们与您的单元测试混为一谈。
          猜你喜欢
          • 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
          相关资源
          最近更新 更多