【问题标题】:What code coverage annotation to use in PhpUnit when a test inherits from an abstract test that tests an abstract class?当测试从测试抽象类的抽象测试继承时,在 PhpUnit 中使用什么代码覆盖注释?
【发布时间】:2020-05-31 18:04:11
【问题描述】:

假设我有这些课程:

abstract class A;
class X extends A;
class Y extends A;

假设我有这些测试:

abstract class ATest extends TestCase;
class XTest extends ATest;
class YTest extends ATest;

这样,我确保XY 不会“破坏/松散”基类A 的预期行为,同时我不必对常见事物重复测试(它们在ATest 中被分解)。

如果XTestYTest 覆盖ATest 的方法,他们很可能会调用parent::whatever()(或不调用,取决于行为),但ATest 中的方法可能不会被覆盖,它们将在调用时像属于 XTestYTest 的测试一样被调用。

好的,到这里为止。

如果我设置了这些覆盖注释:

/** @covers \My\Nice\Project\A */
abstract class ATest extends TestCase

/** @covers \My\Nice\Project\X */
class XTest extends ATest

/** @covers \My\Nice\Project\Y */
class YTest extends ATest

然后当我使用 --coverage-html 运行 phpunit 运行器时,我得到 XY 覆盖 100%,但 A 覆盖 0%。

原因是 ATest 从未真正被测试运行程序调用,因为它是一个抽象测试类(运行程序无法实例化它),并且在运行它的测试时,它实际上是通过 XTestYTest 扩展。

问题

我希望覆盖class A,而我不想在没有@covers 注释的情况下离开测试。

可能的解决方案

abstract class ATest extends TestCase

/**
  * @covers \My\Nice\Project\X
  * @covers \My\Nice\Project\A
  */
class XTest extends ATest

/**
  * @covers \My\Nice\Project\Y
  * @covers \My\Nice\Project\A
  */
class YTest extends ATest

问题

我觉得里面有味道。

这是正确的方法吗?如果不是,我应该如何告诉 phpunit TestA 覆盖 A 并将此元信息扩展到 TestXTestY

注意:此项目使用 PHPUnit 6.5.11。

【问题讨论】:

    标签: inheritance annotations phpunit abstract-class code-coverage


    【解决方案1】:

    覆盖抽象类并没有难闻的气味。这就是代码覆盖的工作方式。有代码,所以你必须覆盖它。

    ATest 也是一个抽象类没关系。 ATest 类不是测试用例。但我知道你的意思。 PHP中没有注释,它仍然是注释。所以没有继承的一部分。

    也许.. 不好的气味来自继承问题,您应该考虑组合而不是继承或策略模式。以我的经验,主要是遗留软件中的问题。

    【讨论】:

    • 嗯...在这种情况下,继承是正确的情况,而不是组合。我最终选择让 XTest 只覆盖 X,然后 YTest 只覆盖 Y。并添加另一个测试:AConcreteTest,它测试一个不在 src/ 中但在测试/助手中的类,这是 A 的具体实现,专门实现使 A 工作并使 AConcreteTest 测试 X 和 Y 的“公共部分”所需的最少功能。这种方法使一切变得干净。在@covers AConcreteTest 中据说覆盖了 A,而不是 AConcrete。
    猜你喜欢
    • 2017-12-23
    • 1970-01-01
    • 2010-09-16
    • 2020-03-12
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多