2012-03-16 101 views
72

我正在嘗試使用PHPunit來測試輸出一些自定義頭文件的類。PHPUnit測試PHP頭文件

的問題是,我的機器上這一點:

<?php 

class HeadersTest extends PHPUnit_Framework_TestCase { 

    public function testHeaders() 
    { 
     ob_start(); 

     header('Location: foo'); 
     $headers_list = headers_list(); 
     header_remove(); 

     ob_clean(); 

     $this->assertContains('Location: foo', $headers_list); 
    } 
} 

,甚至這樣的:

<?php 

class HeadersTest extends PHPUnit_Framework_TestCase { 

    public function testHeaders() 
    { 
     ob_start(); 

     header('Location: foo'); 
     header_remove(); 

     ob_clean(); 
    } 
} 

這個錯誤:

[email protected] [~/test]# phpunit --verbose HeadersTest.php 
PHPUnit 3.6.10 by Sebastian Bergmann. 

E 

Time: 0 seconds, Memory: 2.25Mb 

There was 1 error: 

1) HeadersTest::testHeaders 
Cannot modify header information - headers already sent by (output started at /usr/local/lib/php/PHPUnit/Util/Printer.php:173) 

/test/HeadersTest.php:9 

FAILURES! 
Tests: 1, Assertions: 0, Errors: 1. 

這看起來好像有別的東西在測試運行之前輸出到終端,即使沒有包含其他文件並且沒有其他字符在PHP標籤開始之前。它可能是PHPunit內導致這種情況的東西嗎?

問題是什麼?

+11

只是想,如果有興趣在此另一些人,以及覆蓋這一點。在運行PHPunit(使用PHP CLI)時,headers_list()不起作用,但xdebug_get_headers()可以起作用。 – titel 2012-03-18 17:26:23

回答

103

問題是PHPUnit會在屏幕上打印一個標題,並且此時您不能添加更多標題。

解決方法是在單獨的過程中運行測試。下面是一個例子

<?php 

class FooTest extends PHPUnit_Framework_TestCase 
{ 
    /** 
    * @runInSeparateProcess 
    */ 
    public function testBar() 
    { 
     header('Location : http://foo.com'); 
    } 
} 

這將導致:

$ phpunit FooTest.php 
PHPUnit 3.6.10 by Sebastian Bergmann. 

. 

Time: 1 second, Memory: 9.00Mb 

OK (1 test, 0 assertions) 

的關鍵是@runInSeparateProcess註解。

如果您正在使用PHPUnit的〜4.1或東西,得到錯誤:

PHP Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in -:378 
Stack trace: 
#0 {main} 
    thrown in - on line 378 

Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378 

Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378 

Call Stack: 
    0.0013  582512 1. {main}() -:0 

嘗試添加到您的引導文件來解決它:

<?php 
if (!defined('PHPUNIT_COMPOSER_INSTALL')) { 
    define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/path/to/composer/vendors/dir/autoload.php'); 
} 
+7

中有一些定義這個導致錯誤()語句 PHPUnit_Framework_Exception:注意:恆XYZ已經定義 – mebjas 2014-07-02 21:04:33

+1

@mebjas聽起來無關。 – SamHennessy 2014-07-02 21:40:38

+0

我的意思是如果我必須在phpunit中測試頭文件,並且在我的代碼中有'define'語句,這種方法會導致錯誤,正如我所提到的 – mebjas 2014-07-04 21:28:53

88

雖然運行測試在一個單獨的過程確實解決了這個問題,當運行一大套測試時,會有明顯的開銷。

我的修復是直接PHPUnit的輸出到標準錯誤,像這樣:

phpunit --stderr <options> 

這應該解決的問題,這也意味着,你不必在創建一個包裝功能和全部替換你的代碼。

+3

太棒了!沒有改變我的代碼,沒有單獨的進程,它的工作原理。 – alexfernandez 2012-10-28 18:19:14

+0

但我仍然會看到我所做的錯誤並獲得error_reporting(E_ALL)的輸出? – spankmaster79 2013-04-02 09:27:48

+1

@ spankmaster79是的,它只會去你的終端的標準錯誤。默認情況下,大多數終端會一起打印標準錯誤和標準錯誤,但它們實際上是分開的流。 – 2013-04-02 10:22:12

3

我有一個更激進的解決方案,以便在我的測試/包含文件中使用$_SESSION。 我編輯的PHPUnit的文件中的一個,在../PHPUnit/Utils/Printer.php有一個"session_start();"命令「打印$緩衝區」

它對我來說就像一個魅力。但是我認爲「joonty」用戶的解決方案是迄今爲止最好的。

+0

您是否在存儲庫中提交了拉取請求?我想這可能是一個普遍的問題。 – t1gor 2015-01-05 17:58:56

+0

謝謝你的提示,我在PHPUnit的bootstrap.php中所謂的session_start()和它的作品對我來說 – bumperbox 2015-06-08 03:49:49

-1

的替代解決方案是@runInSeparateProcess PHPUnit的運行時指定--process隔離選項:

[email protected] [~/test]# phpunit --process-isolation HeadersTest.php 

即類似於設置processIsolation =「真」,在phpunit.xml選項。

該解決方案具有類似的優勢/劣勢指定--stderr選項,但並沒有我的情況下工作。基本上不需要更改代碼,即使可能會由於在單獨的PHP進程中運行每個測試而導致性能下降。

+0

這可能是在追查原因,並做一些測試的第一步,但爲了創建維護測試,只需直接嵌入註釋到測試文件中。命令行中需要的「特殊」選項越少,CI系統配置的維護就越容易。 – Shi 2017-09-03 20:51:42

4

順便說一句:對我來說headers_list()保持返回0元素。我注意到這個問題@titel的意見和揣摩它值得在這裏特別提到:

Just wanted to cover this if there are some other people interested in this as well. headers_list() doesn't work while running PHPunit (which uses PHP CLI) but xdebug_get_headers() works instead.

HTH

在評論已經提到
0

正如,我認爲這是一個更好的解決方案在XML配置文件來定義processIsolation像

 <?xml version="1.0" encoding="UTF-8"?> 
    <phpunit 
     processIsolation   = "true" 
     // ... 
    > 
    </phpunit> 

像這樣,你不必通過--stderr選項,這可能會刺激你的同事。

+1

它可能是更好地定義它只是需要它的測試。爲所有測試設置它只會使運行測試變慢。 – Shi 2017-09-03 20:48:02