我收到的错误与此完全相同:
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并用print $buffer
包裹if (strpos($buffer, 'PHPUnit 3.5.10 by Sebastian Bergmann') === false)
行(有效地停止PHPUnit的第一行输出),那么我的第一次测试成功(直到测试用例输出一个指示测试成功的点,然后下一个测试失败,因为输出了点。)
我团队中的另一位开发人员能够成功运行完整的测试套件,所以我知道这不是应用程序代码的问题。它必须是我的本地环境的一些配置设置或问题。
我已经检查过php.ini,以确认output_buffering
已开启且implicit_flush
已关闭,而且已关闭。
我也尝试将Zend_Session::$_unitTestEnabled = true;
添加到我的测试引导程序中,但这没有任何帮助(并且无论如何都不应该是必要的,因为它适用于其他开发人员的计算机以及没有它的CI服务器上。)< / p>
除了忽略错误之外的任何建议?我从来没有见过这样的东西,真的不知所措。
谢谢!
更新
为了尝试进一步隔离问题,我通过执行以下测试脚本将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。
答案 0 :(得分:37)
使用-stderr标志运行phpunit,(较新的版本可能使用--stderr),例如。
phpunit -stderr mytest.php
# or
phpunit --stderr mytest.php
这将phpunit的输出定向到stderr,防止它中断HTTP标头的生成。
测试可能在你朋友的机器上运行,因为他启用了输出缓冲(虽然我不确定它是否与CLI上下文相关)。
答案 1 :(得分:6)
我认为更好的方法是使用
Zend_Session::$_unitTestEnabled = true;
在我的测试引导程序中使用它可以防止出现此错误。
答案 2 :(得分:1)
如果PHPUnit在您的系统上使用的php二进制文件是CGI而不是CLI版本,那么session_start
实际上将尝试设置cookie并且您将收到该错误。
您可以通过调用php_sapi_name
来检查以确定您正在使用的SAPI。
答案 3 :(得分:0)
我在另一个项目中遇到了同样的问题,我发现问题是PHPUnit导致输出过早启动,因为它在运行测试之前输出了欢迎消息。
将以下两行添加到bootstrap.php
:
ini_set('session.use_cookies', 0);
ini_set('session.cache_limiter', '');
这可以防止在测试套件运行之前发送标头。
答案 4 :(得分:0)
就像Makor所说的那样,你只需要在你的 bootstrap.php 中添加它
Zend_Session::$_unitTestEnabled = true;
就我而言,我在 bootstrap.php 文件中添加了类似的内容
if(APPLICATION_ENV == 'testing' && php_sapi_name() == 'cli') {
Zend_Session::$_unitTestEnabled = true;
}
所以你不必再改变它了。