【问题标题】:How to determine if an existing class can be unit-tested?如何确定现有类是否可以进行单元测试?
【发布时间】:2011-01-25 16:24:12
【问题描述】:

最近,我拥有了一些 c++ 代码。我将维护此代码,并在以后添加新功能。 我知道很多人说通常不值得在现有代码中添加单元测试,但我仍然想添加一些至少部分覆盖代码的测试。特别是,我想添加一些测试来重现我修复的错误。

有些类是用一些非常复杂的状态构造的,这会使单元测试变得更加困难。

我也愿意重构代码以使其更易于测试。

您是否推荐了任何关于指南的好文章,以帮助识别更容易进行单元测试的类?你有什么自己的建议吗?

【问题讨论】:

  • “我知道很多人说通常不值得在现有代码中添加单元测试......”

标签: c++ unit-testing


【解决方案1】:

虽然 Martin Fowler 关于重构的书是一个信息宝库,但不妨看看“Working Effectively with Legacy Code”。

此外,如果您要处理存在大量全局变量或大量状态转换的类,我会进行大量集成检查。尽可能多地分离出与您正在重构的代码交互的代码,以确保所有预期的输入按照它们接收的顺序继续产生相同的输出。这很关键,因为“修复”可能已在其他地方解决的细微错误非常容易。

也记笔记。如果您确实发现存在另一个函数/类期望并正确处理的错误,您将希望同时更改两者。除非您保留完整的记录,否则这很困难。

【讨论】:

    【解决方案2】:

    大概代码是为了某个目的而编写的,单元测试会检查是否满足目的,即方法的前置条件和后置条件是否成立。

    如果公共类方法可以从外部检查状态,那么它可以很容易地进行单元测试(黑盒测试)。如果类状态是不可见的,或者如果您必须测试棘手的私有方法,您的测试类可能需要成为朋友(白盒测试)。

    一个难以进行单元测试的类将是一个

    • 具有巨大的依赖关系,即紧密耦合
    • 旨在在大容量或多线程环境中工作。在那里,您将使用系统测试而不是单元测试,实际输出可能无法完全确定。

    【讨论】:

      【解决方案3】:

      我写了很多关于单元测试、重要的 C++ 代码的博客文章:http://www.lenholgate.com/blog/2004/05/practical-testing.html

      我还写了很多关于向现有代码添加测试的文章:http://www.lenholgate.com/blog/testing/

      【讨论】:

        【解决方案4】:

        几乎所有东西都可以而且应该进行单元测试。如果不是直接使用,则使用模拟类。

        既然您决定重构您的类,请尝试使用 BDD 或 TDD 方法。

        为防止破坏现有功能,唯一的方法是进行良好的集成测试,但对于复杂的系统,通常需要时间来执行所有测试。

        如果没有更多关于你所做的事情的详细信息,就很难提供更多的实现细节。有些是:

        • 首先使用 MVP 或 Presenter 开发 gui
        • 在适当的地方使用设计模式
        • 使用函数和成员指针,或观察者设计模式来打破依赖关系

        【讨论】:

        • 解决方案通常在于部署大量的 TLA
        • @CashCow TLA? TLA 代表什么?
        【解决方案5】:

        我认为,如果您必须想出一些“衡量标准”来测试一个类是否可测试,那么您已经完蛋了。你应该能看出来:你能写一个独立的程序,单独链接到这个类并确保它工作吗?

        如果一个类太大以至于你不能仅仅通过查看它来确定......它可能是不可测试的。不知道如何制作小而独特的界面的人通常也不知道如何遵守任何其他原则。

        最后,确定一个类是否可测试的方法是尝试将它放在一个工具中。如果您最终不得不将一半的程序拉入其中,请尝试重构。如果你发现你甚至不能执行最基本的重构,而不必重写整个程序,请分析这样做的代价。

        【讨论】:

          【解决方案6】:

          我们在 IPL 发表了一篇论文 It's testing Jim, but not as we know it,该论文探讨了测试 C++ 的实际问题,并提出了一些技术来解决这些问题,这些技术可能对您的问题很有用。这些技术在我们的 C/C++ 单元和集成测试工具 Cantata++ 中也得到了很好的支持。

          【讨论】:

            猜你喜欢
            • 2017-09-27
            • 2010-09-08
            • 1970-01-01
            • 1970-01-01
            • 2013-06-04
            • 1970-01-01
            • 1970-01-01
            • 2016-07-21
            • 1970-01-01
            相关资源
            最近更新 更多