1

我有两个班级,父母和孩子:

class Parent
{
    public function parentAction() {...}
}

class Child extends Parent
{
    public function childAction() {...}
}

现在我正在用 PHPUnit 测试这些。(我并不是真正的单元测试,但出于问题的目的,我想你可以假设我是。我用这些测试类来做这个:

abstract class ParentBaseTest extends PHPUnit_Framework_TestCase
{
    public function testParentAction() {...}

    protected function factoryMethod() 
    {
        return new Parent();
    }
}

class ParentTest extends ParentBaseTest
{
}

class ChildTest  extends ParentBaseTest
{
    protected function factoryMethod()
    {
        return new Child();
    }

    public function testChildAction() {...}
}

在这里使用 factoryMethod 继承的想法是,无需为 Parent 重写测试,来自 ParentBaseTest 的测试也将在 Child 上运行。换句话说,检验的是 Child 是否正确地遵守了 Liskov 替换原则。使用抽象基类和空继承类是必要的,因为 PHPUnit 感觉不像运行你的基类测试两次。

以上所有工作。但是,现在我想添加一个依赖testParentAction()testChildAction()(即在定义/** @depends testParentAction */之前添加testChildAction())。

这不起作用。因为 PHPUnit 不会改变运行测试的顺序以满足依赖关系,并ChildTest在运行它继承的测试之前运行定义的测试ParentTest,所以它总是会导致testChildMethod()被跳过。

是否可以强制 PHPUnit 先运行继承的测试?或者是否有另一种(干净的)方法来强制执行依赖?

4

1 回答 1

1

我认为这里对单元测试存在误解。虽然您的 OOP 理论是准确的,但它并不能很好地应用于单元测试领域,让我解释一下我的观点。

每个测试用例类都应该测试给定类的所有行为,并且该类中的每个测试用例都应该测试被测类中每个方法的一小部分。这意味着在测试类中拥有一个工厂方法是没有意义的,因为它不应该改变或接收不同的实例来测试,否则它将为该类测试错误的东西。在设置中,您可以实例化共享夹具,并且子类或父类在其各自测试类的所有测试用例之间共享。

单元测试用例也应该独立运行,因此您可以自由运行给定的测试用例并且它应该通过,并且没有其他测试用例应该依赖此结果来通过或失败,否则您的测试中会有随机行为从来不是一件好事。所以 Child 测试不应该依赖于 Parent 的测试,而 Parent 不应该依赖于 Child 的测试(即使在 OOP 中,父类也应该不知道它的子类)。

此外,测试用例可以以不同的顺序运行,这不应该影响测试的正确性,因为正如我所说,每个测试用例都应该能够独立运行。

如果您想了解更多关于如何做好单元测试的信息,我强烈推荐这本书:http ://www.amazon.com/Effective-Unit-Testing-guide-Developers/dp/1935182579/ref=sr_1_3?ie=UTF8&qid =1372014749&sr=8-3&keywords=unit+testing它面向 Java 开发人员,但理论在所有框架之间共享,它们有完整的测试气味部分以及如何修复和防止它们。

于 2013-06-23T19:16:55.877 回答