27

我收到了许多与此完全相同的错误:

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 $bufferif (strpos($buffer, 'PHPUnit 3.5.10 by Sebastian Bergmann') === false)(有效地停止 PHPUnit 的第一行输出)换行,那么我的第一个测试成功(直到测试用例输出一个点表示测试成功,然后下一个测试失败,因为点已输出)。

我团队中的另一位开发人员能够成功运行完整的测试套件,所以我知道这不是应用程序代码的问题。一定是我的本地环境的一些配置设置或问题。

我已经检查了 php.ini 以验证它output_buffering是否已打开和implicit_flush关闭,并且它们是。

我也尝试添加Zend_Session::$_unitTestEnabled = true;到我的测试引导程序中,但这并没有帮助(无论如何也不应该有必要,因为它可以在另一个开发人员的机器上以及没有它的情况下在我们的 CI 服务器上工作)。

除了忽略错误之外还有什么建议吗?我从来没有见过这样的事情,我真的很茫然。

谢谢!

更新:

为了尝试进一步隔离问题,我通过执行以下测试脚本将 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。

4

5 回答 5

37

使用 -stderr 标志运行 phpunit,(新版本可能使用 --stderr 代替)例如

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

这会将 phpunit 的输出定向到 stderr,从而防止它中断 HTTP 标头生成。

测试可能在您朋友的机器上运行,因为他启用了输出缓冲(尽管我不确定这在 CLI 上下文中是否相关)。

于 2011-04-01T03:20:51.153 回答
6

我认为更好的方法是使用

Zend_Session::$_unitTestEnabled = true;

在我的测试引导程序中使用它可以防止出现此错误。

于 2014-01-08T15:14:25.887 回答
1

如果 PHPUnit 在你的系统上使用的 php 二进制文件是 CGI 而不是 CLI 版本,那么session_start你真的会尝试设置 cookie,你会得到那个错误。

您可以通过调用来检查以确保您使用的是什么 SAPI php_sapi_name

于 2011-04-01T03:01:35.543 回答
0

我在另一个项目中遇到了同样的问题,我发现问题是 PHPUnit 导致输出启动过早,因为它在运行测试之前输出了欢迎消息。

将以下两行添加到bootstrap.php

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

这应该可以防止在您的测试套件运行之前发送标头。

于 2014-02-07T19:54:13.230 回答
0

就像Makor说的,你只需要在你的bootstrap.php中添加这个

Zend_Session::$_unitTestEnabled = true;

就我而言,我在bootstrap.php文件中添加了类似的内容

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

所以你不必再改变它了。

于 2017-03-20T13:42:04.410 回答