用PHPUnittestingPHP头文件

我正在尝试使用PHPunit来testing输出一些自定义标头的类。

问题是,在我的机器上:

<?php class HeadersTest extends PHPUnit_Framework_TestCase { public function testHeaders() { ob_start(); header('Location: foo'); $headers_list = headers_list(); header_remove(); ob_clean(); $this->assertContains('Location: foo', $headers_list); } } 

甚至这个:

 <?php class HeadersTest extends PHPUnit_Framework_TestCase { public function testHeaders() { ob_start(); header('Location: foo'); header_remove(); ob_clean(); } } 

返回这个错误:

 name@host [~/test]# phpunit --verbose HeadersTest.php PHPUnit 3.6.10 by Sebastian Bergmann. E Time: 0 seconds, Memory: 2.25Mb There was 1 error: 1) HeadersTest::testHeaders Cannot modify header information - headers already sent by (output started at /usr/local/lib/php/PHPUnit/Util/Printer.php:173) /test/HeadersTest.php:9 FAILURES! Tests: 1, Assertions: 0, Errors: 1. 

这看起来好像在testing运行之前还有别的东西输出到terminal上,即使没有其他文件包含在内,PHP标签开始之前也没有其他字符。 它可能是PHPunit内部的东西造成这个?

这个问题可能是什么?

问题是PHPUnit会在屏幕上打印一个标题,那时你不能添加更多的标题。

解决方法是在一个孤立的过程中运行testing。 这是一个例子

 <?php class FooTest extends PHPUnit_Framework_TestCase { /** * @runInSeparateProcess */ public function testBar() { header('Location : http://foo.com'); } } 

这将导致:

 $ phpunit FooTest.php PHPUnit 3.6.10 by Sebastian Bergmann. . Time: 1 second, Memory: 9.00Mb OK (1 test, 0 assertions) 

关键是@runInSeparateProcess注释。

如果你正在使用PHPUnit〜4.1或其他东西,并得到错误:

 PHP Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in -:378 Stack trace: #0 {main} thrown in - on line 378 Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378 Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378 Call Stack: 0.0013 582512 1. {main}() -:0 

尝试添加到您的引导文件来解决它:

 <?php if (!defined('PHPUNIT_COMPOSER_INSTALL')) { define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/path/to/composer/vendors/dir/autoload.php'); } 

虽然在单独的进程中运行testing确实解决了这个问题,但是运行一大套testing时会有明显的开销。

我的修复是将phpunit的输出指向stderr,如下所示:

 phpunit --stderr <options> 

这应该解决这个问题,这也意味着你不必创build一个包装函数,并replace你的代码中的所有事件。

headers_list()说一下:对于我来说headers_list()保持返回0个元素。 我注意到@titel对这个问题的评论,并认为这里值得特别提一下:

如果还有其他一些人对此感兴趣的话,只是想说明一下。 在运行PHPunit(使用PHP CLI)时, headers_list()不起作用,但是xdebug_get_headers()起作用。

HTH

我有一个更激进的解决scheme,以便在我的testing/包含文件中使用$_SESSION 。 我在../PHPUnit/Utils/Printer.php中编辑了一个PHPUnit文件, 使其具有"session_start();"命令“print $ buffer”之前

它对我来说就像一个魅力。 但我认为“joonty”用户的解决scheme是迄今为止最好的。

正如在评论中已经提到的,我认为这是一个更好的解决scheme,像在XMLconfiguration文件中定义processIsolation

  <?xml version="1.0" encoding="UTF-8"?> <phpunit processIsolation = "true" // ... > </phpunit> 

像这样,你不必通过 – stderr选项,这可能会激怒你的同事。

对于@runInSeparateProcess的替代解决scheme是在运行PHPUnit时指定–process-isolation选项:

 name@host [~/test]# phpunit --process-isolation HeadersTest.php 

这类似于在phpunit.xml中设置processIsolation =“true”选项。

该解决scheme与指定–stderr选项类似的优点/缺点,但是在我的情况下不起作用。 基本上不需要更改代码,即使可能会由于在单独的PHP进程中运行每个testing而导致性能下降。