2011-03-31 49 views
26

我得到許多錯誤正是這樣一個:PHPUnit的輸出造成了Zend_Session例外

Zend_Session_Exception: Session must be started before any output has been sent to the browser; output started in /usr/local/zend/share/pear/PHPUnit/Util/Printer.php/173 

當運行我的應用程序的測試套件。這是PHPUnit 3.5.10和PHP 5.3.5。

有沒有神祕的,意想不到的空白輸出是造成這種情況。我已經確定「正在發送到瀏覽器的輸出」是正在執行的PHPUnit測試的實際輸出。如果我打開PHPUnit/Util/Printer.php並使用if (strpos($buffer, 'PHPUnit 3.5.10 by Sebastian Bergmann') === false)(有效地停止來自PHPUnit的第一行輸出)包裝print $buffer行,那麼我的第一個測試會成功(直到測試用例輸出一個表示測試成功的點)下一個測試失敗,因爲點被輸出)。

我的團隊中的另一位開發人員能夠成功運行完整的測試套件,所以我知道這不是應用程序代碼的問題。它必須是一些配置設置或我的本地環境問題。

我已經檢查了php.ini來驗證output_buffering已打開,並且已關閉​​,它們是。

我也試過把Zend_Session::$_unitTestEnabled = true;添加到我的測試引導中,但這並沒有幫助(因爲它可以在另一個開發人員的機器上運行,而且在我們的CI服務器上沒有運行它也不需要)。

除了忽略錯誤之外,還有什麼建議嗎?我從來沒有見過這樣的事情,真的很茫然。

謝謝!

UPDATE:

爲了試圖進一步孤立的問題,我把ZF和我的應用程序的方程通過執行以下的測試腳本:

<?php 

class SessionTest extends PHPUnit_Framework_TestCase 
{ 
    public function testSession() 
    { 
     session_start(); 
     $this->assertTrue(true); 
    } 
} 

測試失敗:

1) SessionTest::testSession 
session_start(): Cannot send session cookie - headers already sent by (output started at /home/mmsa/test.php:1) 

但是,完全相同的測試適用於朋友的機器。相同版本的PHP和PHPUnit。

回答

37

使用-stderr標誌運行phpunit,(較新的版本可以使用--stderr代替)例如

phpunit -stderr mytest.php 
# or 
phpunit --stderr mytest.php 

這會將phpunit的輸出指向stderr,防止它中斷HTTP標頭生成。

測試可能在朋友的機器上運行,因爲他啓用了輸出緩衝(雖然我不確定這是否與CLI環境相關)。

+0

不理會我以前的評論 - 這實際上**做了**工作。我在昨天晚上試圖弄清楚這一點時,仍然在PHPUnit核心中有一些調試代碼。當我恢復它時,'--stderr'標誌允許測試工作。謝謝!不過,這是一種解決方法。如果它在沒有'--stderr'標誌的另一臺機器上工作,那麼它應該在我的工作。從我可以告訴,我沒有輸出緩衝禁用。我還能檢查什麼? – 2011-04-01 13:18:04

+1

它可能是新版本中的「--stderr」(當然會更標準),但是我的(有點過時的)安裝phpunit只支持'-stderr'。由於此會話問題,我們在運行所有測試時使用'-stderr'。至於你的環境之間可能有什麼不同,我只能建議比較兩臺機器上的php -i的輸出以查找配置差異。 – 2011-04-01 18:15:44

+1

這對我也適用。不幸的是,似乎沒有(但)似乎是爲此輸入'phpunit.xml'的選項。 – dave1010 2011-06-07 10:12:26

1

如果PHPUnit在您的系統上使用的php二進制文件是CGI而不是CLI版本,那麼session_start確實會嘗試設置cookie,您會得到該錯誤。

您可以通過致電php_sapi_name確認您使用的是SAPI。

+0

'echo php_sapi_name();'outputs「cli」 – 2011-04-01 03:13:24

+0

我唯一要說的是我的頭頂是確保'pear config-show | grep php_bin'列出了你期望的相同的二進制文件。 – 2011-04-01 03:20:44

+0

它指向'/ usr/local/zend/bin/php',這是我環境中唯一的PHP安裝。 – 2011-04-01 12:59:51

6

我認爲更好的辦法是使用

Zend_Session::$_unitTestEnabled = true; 

在我的測試引導使用這種從這個錯誤阻止。

0

我與另一個項目有同樣的問題,我發現問題是PHPUnit導致輸出過早開始,因爲它在運行測試之前輸出它的歡迎消息。

添加以下兩行bootstrap.php

ini_set('session.use_cookies', 0); 
ini_set('session.cache_limiter', ''); 

這可以防止頭從你的測試套件運行前發送。

0

Makor說,你只需要在你的bootstrap.php中

Zend_Session::$_unitTestEnabled = true; 

添加這個在我的情況,我把類似的東西在我的bootstrap.php中文件

if(APPLICATION_ENV == 'testing' && php_sapi_name() == 'cli') { 
    Zend_Session::$_unitTestEnabled = true; 
} 

所以你不必改變它了。