【问题标题】:How do unit tests change when a base class is driven out?当基类被淘汰时,单元测试如何变化?
【发布时间】:2011-08-02 16:25:05
【问题描述】:

这是对this question 的部分跟进。

我不确定问这个问题的最佳方式,所以我会尝试一个短篇故事来设置场景:

曾几何时,有一个类“A”,它有一个单元测试类“ATests”,负责通过公共接口测试其行为。他们一起幸福地生活了一段时间,然后发生了变化,“B”类出现了,事实证明它与“A”类有很多共同之处,所以引入了一个基类。

A 类的测试已经涵盖了基类的公共行为。那么,问题是接下来会发生什么?

• B 类是否需要对通用(基类行为)进行测试?似乎该行为是 B 的一部分,因此应该对其进行测试,但是这些测试是否应该与 A 类的测试共享?对于基类?如果是这样,最好的分享方式是什么?

• 新的基类是否需要单元测试,或者基类可以通过其子类的测试进行测试吗?基类是否抽象有关系吗?

• 确保类 A 和 B 派生自基类并“信任”基类的单元测试以测试常见行为是否足够(因此不需要在子类中复制测试)? A & B 的测试只需要测试它们是新的/改变的行为吗?

• 我是否完全采用了错误的方法,每个真实课程大约有一个单元测试课程?

我在不同的时间采取了不同的观点,不同的方法会对重构代码的能力、编写测试所花费的时间等产生相当大的影响。人们发现哪些方法最有效?

【问题讨论】:

    标签: unit-testing tdd


    【解决方案1】:

    就个人而言,如果有时间,我倾向于测试所有三个(基础和两个派生)。它表明您不会无意中重写基方法并更改它们的行为,并且您继承的类仍然提供预期的语义。如果行为真的没有改变,那么它可能就像复制粘贴工作一样简单,但它提供了更完整的覆盖范围。

    不过,请注意“给定时间”部分。如果时间是一个问题(而且总是如此),那么测试基类或继承的功能可能是较低的优先级。但是测试是对你自己的很好的预防接种,让你在以后重构时更有信心,所以你只是在缩短你自己、你的客户和/或你的维护者,因为你没有尽你的时间做完整的覆盖。

    但是,如果您有专门的测试人员或 QA 团队(如果有的话),则完全可以接受此类重复性事情。但有时请他们喝啤酒 :-) 他们让你看起来更好!

    【讨论】:

    • -1,不管你有什么时间限制,不做适当的单元测试会比做它更昂贵。
    【解决方案2】:

    您可能会查看代码覆盖率工具;如果您实际上正在测试所有代码,他们可以告诉您。就个人而言,如果我有一个涵盖基类行为的测试并且我没有覆盖它,我不会再次测试它。目标是让代码更改(可能)只破坏一个测试。

    不要觉得每个真实课程都需要一个单元测试课程。每个独特的设置夹具一个单元测试类是一种方法,然后是整个BDD school...

    【讨论】:

    • 我从来没有真正发现代码覆盖工具特别有用,而无需花费大量精力。知道测试运行了一些代码并不等于知道代码已经过测试。
    • 如果我只对基类中的常见行为进行测试,我怎么知道“A/B 类”的行为类似于“基类”?你是说我真的不需要知道吗?你测试 A 是从基数派生的吗?
    • @forsvarir:同意,仅覆盖并不能保证良好的测试。但是如果类 Base 有方法 X 被测试覆盖并且类 Descendant 没有覆盖 X,则不需要重新测试 Descendant.X。为变化的行为添加测试。
    • @TrueWill:我认为我非常同意,但问题是,如果出现可以通过扩展 B 类来实现的需求,而是由开发人员“修复”基类,该怎么办。 A 类的行为也被“修复”改变了,它可能正确也可能不正确,并且没有测试可以捕捉到它。
    • @forsvarir:单元测试不能保护你的代码不被愚弄。它们指导设计、检查逻辑、为重构提供部分安全网、验证一些类级别的行为、捕获一些错误并提供有限的回归测试。这就是您需要多层测试的原因;特别是端到端验收测试(不是单元测试)。
    【解决方案3】:

    重构测试代码与重构生产代码同样重要。两者都应被视为一等公民。因此,如果您将公共方法提取到基类中,那么它应该有自己的一组测试。如果您的测试用例设计正确,每个测试都测试一件事,那么测试重构应该很容易。

    如果您要提取受保护的功能,那么它可能是一个略带灰色的区域。如果测试方法对类来说是新的,那么我希望它们在派生类中进行测试,因为它们可能存在于派生类中以正常运行。理想情况下,这应该保持在最低限度,因为基类功能变得不那么明显了。

    然后,派生类将在他们自己的一组测试中测试剩余的公共方法。

    同样,如果您更改的是生产代码而不是测试,那么您应该合并一个覆盖工具,这样您就可以确信您的测试已经被充分覆盖了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-21
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 2015-03-31
      • 1970-01-01
      相关资源
      最近更新 更多