2013-03-14 35 views
1

我打电话给phpunit,其参数是一个目录(奖金问题:为什么不能接受一个文件列表?),现在它正在抱怨一个班级被宣布不止一次,因为包含在之前的文件测试!phunit如何处理多个关于需要/包含的文件?

如果我运行phpunit firstTest.php; phpunit secondTest.php一切正常

phpunit ./失败PHP Fatal error: Cannot redeclare class X

我的测试基本上都是:

include 'class_to_be_tested.php' 
class class1Test extends... 

,别无其他。我正在使用选项--process-isolation。我可以在我的课上添加require_once,但那不是我想要能够单独测试它们的。

不应该phpunit遵循最佳测试实践并运行一个测试,清除它所拥有的任何垃圾,在干净状态下运行另一个测试?或者我做错了什么?

回答

1

方式PHPUnit的工作意味着你所有的测试都在一个单一的PHP程序的上下文中运行。 phpUnit旨在隔离彼此的测试,但它们都在相同的程序执行中运行。

PHP的include声明将包含所请求的文件,而不管它是否已包含在之前。这意味着如果include给定的班级两次,您将会再次发生错误。这在您的测试中发生,因为每个测试都包含相同的文件,但没有考虑是否已经包含在其他测试中。

解决方案:

  • 包装你include电话与if(class_exists('classname')),这样你不包括,如果类已经被定义的文件。

  • 将文件包含在phpUnit引导文件中而不是在测试中。

  • 使用include_once(或甚至require_once)而不是include

  • 任意停止包含文件,并开始使用自动加载器。

2

既然你有include而不是include_once并且你的问题中没有显示其他代码,那么无法重新声明错误也可能是你再次在被测代码中的某个地方包含该文件。

假设情况并非如此,那么在--process-isolation后面会出现一些可以保留全局类声明的事情。本博客文章给出了更详细:http://matthewturland.com/2010/08/19/process-isolation-in-phpunit/

基本上,你会想建立自己的基地TestCase,并重写run()方法设置preserveGlobalStatefalse。这应该适当地让所有的测试一起运行。

的基类将类似于这样(从博客文章采取我简称):

class MyTestCase extends PHPUnit_Framework_TestCase 
{ 
    public function run(PHPUnit_Framework_TestResult $result = NULL) 
    { 
     $this->setPreserveGlobalState(false); 
     return parent::run($result); 
    } 
} 
1

变化:

include 'class_to_be_tested.php'; 
class class1Test extends... 

是:

include_once 'class_to_be_tested.php'; 
class class1Test extends... 

在PHP你需要有一个真正的好理由来使用前者。

关于为什么不能接受文件列表?,我认为设计决定是你一般不需要。然而,你可以通过创建一个测试套件在phpunit.xml.dist文件做到这一点,看到 http://www.phpunit.de/manual/current/en/organizing-tests.html#organizing-tests.xml-configuration

相关问题