PHPUnit输出导致Zend_Session异常

时间:2011-03-31 19:21:46

标签: php zend-framework 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并用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。

5 个答案:

答案 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;
}

所以你不必再改变它了。