我有两个班,父母和孩子:
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首先运行继承的测试?或者是否有另一种(干净的)方式来强制执行依赖?
答案 0 :(得分:1)
我认为这里存在对单元测试的误解。虽然你的OOP理论是准确的,但它并没有很好地应用于单元测试的领域,让我解释一下我的观点。
每个测试用例类都应该测试给定类的所有行为,并且该类中的每个测试用例都应该测试测试类中每个方法的一小部分。这意味着在测试类中包含一个工厂方法是没有意义的,因为它应该永远不会改变或接收不同的实例进行测试,否则它将测试该类的错误内容。在设置中,您可以实例化共享夹具,Child或Parent类在各自测试类的所有测试用例之间共享。
单元测试用例也应该是独立运行的,所以你可以自由运行给定的测试用例,它应该通过,没有其他测试用例应该依赖于这个结果通过或失败,否则你的行为会随机出现测试从来都不是一件好事。所以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开发人员的,但理论在所有框架之间共享,并且它们有完整的测试气味和如何解决它们并阻止它们。