2011-03-31 60 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; 
} 

所以你不必改变它了。