用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而导致性能下降。