2013-03-14 36 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

相關問題