Phpunit: "headers already sent" problem in isolated tests when running with PHAR

Created on 18 Mar 2014  路  26Comments  路  Source: sebastianbergmann/phpunit

I have some code that emits headers which I have no control of, just like #720 . As suggested, I ran the test in a separated process, and it worked when running with phpunit installed by composer in the vendor/bin directory.

BUT, it does not work when ran with a phpunit PHAR archive, the "headers" still sent, after some digging, I found that it is the first shebang line "#!/usr/bin/env php" in the stup.php that causes this trouble.

If the PHAR is loaded as a library by 'require', the shebang line is absolutely unnecessary.

OR, fix this by calling 'ob_start()' within the https://github.com/sebastianbergmann/phpunit/blob/master/src/Util/PHP/Template/TestCaseMethod.tpl.dist just before the loading of the phar archive, but this is not the way it should be done.

Most helpful comment

I get this problem if I don't use --stderr as a param when running my tests...

All 26 comments

@sebastianbergmann any chance to get a fix for this ? It prevents the Symfony2 testsuite from passing when using the phar

I do not know what the correct fix is. Removing the shebang line from the PHAR stub would render the PHAR unusable, would it not?

@fabpot Do you have an idea how to fix this?

removing it would indeed make it impossible to run phpunit.phar directly, requiring to use php phpunit.phar.

So maybe using the output buffer around the phar inclusion, as suggested by @techlivezheng, could do the trick.
currently, the output buffer is started only after requiring the phar

@sebastianbergmann will the fix get released as a 4.0.19 release, or will it be available ony in 4.1 or 4.2 ?

It will be in 4.0.19.

The fix will also be in PHPUnit 3.7.37.

when do you plan to release it ? This is to let us decide how we handle fixing our Travis builds (running a phpunit --self-update to get the newer 4.0 phar or installing from source with composer)

PHPUnit 3.7.37 and PHPUnit 4.0.19 have been released.

Hi, guys.

I have phpUnit 4.4.1 and the issue still persist. I tries both the phar and composer bin (separated processes and not), but the issue persists.

If separated, I get the following exception:
PHP Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SplFileInfo' is not allowed' in phar:///usr/local/bin/phpunit/phpunit/Util/GlobalState.php:211

If using the composer bin:

Call stack:
Exception: Serialization of 'SplFileInfo' is not allowed in /path/to/project/vendor/phpunit/phpunit/src/Util/GlobalState.php on line 211

  0.0004     641608   1. {main}() /path/to/project/vendor/phpunit/phpunit/phpunit:0
  0.0161    1666672   2. PHPUnit_TextUI_Command::main() /path/to/project/vendor/phpunit/phpunit/phpunit:62
  0.0161    1667712   3. PHPUnit_TextUI_Command->run() /path/to/project/vendor/phpunit/phpunit/src/TextUI/Command.php:138
  0.4945   14352368   4. PHPUnit_TextUI_TestRunner->doRun() /path/to/project/vendor/phpunit/phpunit/src/TextUI/Command.php:186
  2.0006   17549968   5. PHPUnit_Framework_TestSuite->run() /path/to/project/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:423
  4.7326   22223080   6. PHPUnit_Framework_TestSuite->run() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:751
  9.4326   24608496   7. PHPUnit_Framework_TestSuite->run() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:751
  9.4356   24613072   8. PHPUnit_Framework_TestCase->run() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:751
  9.4394   24695088   9. PHPUnit_Util_GlobalState::getGlobalsAsString() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestCase.php:651
  9.4405   24705776  10. PHPUnit_Util_GlobalState::exportVariable() /path/to/project/vendor/phpunit/phpunit/src/Util/GlobalState.php:185
  9.4405   24705856  11. serialize() /path/to/project/vendor/phpunit/phpunit/src/Util/GlobalState.php:211

If not, the headers error:
Cannot modify header information - headers already sent by (output started at phar:///usr/local/bin/phpunit/phpunit/Util/Printer.php:172)

In my code I use the session, but not the headers if this matters.

Does anyone have any idea how can I fix or avoid it?

P.S. Due to this comment it seems that something is wrong with my install of phpUnit.

PHPUnit 4.5.0 - Cannot modify header information - headers already sent by (output started at phar:///usr/local/bin/phpunit/phpunit/Util/Printer.php:137)

I can also confirm that PHPUnit 4.5.1 is outputting Uncaught PHP Exception PHPUnit_Framework_Error_Warning: "Cannot modify header information - headers already sent by (output started at /workspaces/app/tests/vendor/phpunit/phpunit/src/Util/Printer.php:139)"

Also latest PHPunit 4.8.6 is throwing the same error

Cannot modify header information - headers already sent by (output started at phar:///usr/local/zend//tests/phpunit-4.8.5.phar/phar/phpunit/Util/Printer.php:133)

PHPUnit 5.2.0 by Sebastian Bergmann and contributors.

ErrorException: Cannot modify header information - headers already sent by (output started at phar:///usr/bin/phpunit/phpunit/Util/Printer.php:134)

Just because the error message contains "Cannot modify header information" does not mean that this is the same issue.

Well, my test doesn't use anything related with headers. Also, it worked with previous php version, test haven't changed, but now it's throwing this error. So I thought it could be related.

Works fine with single test e.g. --filter=mytest

I also have the same issue:

PHPUnit 5.5.4 by Sebastian Bergmann and contributors.
Starting test 'ExampleTest::testBasicExample'.
Cannot modify header information - headers already sent by (output started at ../vendor/phpunit/phpunit/src/Util/Printer.php:134)

I get this problem if I don't use --stderr as a param when running my tests...

I am having the same issue like it's described here: Maatwebsite/Laravel-Excel/issues/511

this problem can be bypassed by using a custom printer in which you explicitly set `$out' to stdout

I experienced this issue when my controller was redirected to a login page.

Fixed using @victorbstan solution:

bin/phpunit --stderr

I experienced this issue when run Codeception tests in docker container throw PHPStorm.
run codecept directly in Docker container at same tests and config avoid this issue.

Yii2 Alert() widget can't start session

@dynasource STDOUT will be closed here
https://github.com/sebastianbergmann/phpunit/blob/e6e7085fbbd2e25f4ca128ac30c1b0d3dd4ef827/src/Util/Printer.php#L73-L78
this will be redefine too

/**
 * For avoid set headers before session start
 * Class PhpStorm_Codeception_ReportPrinter_Redefine
 */
class PhpStorm_Codeception_ReportPrinter_Redefine extends PHPUnit_TextUI_ResultPrinter
{
    /**
     * @inheritDoc
     */
    public function __construct(
        $out = null,
        $verbose = false,
        $colors = self::COLOR_DEFAULT,
        $debug = false,
        $numberOfColumns = 80,
        $reverse = false
    ) {
        parent::__construct(STDOUT, $verbose, $colors, $debug, $numberOfColumns, $reverse);
    }

    /**
     * Flush buffer and close output if it's not to a STDOUT stream
     */
    public function flush()
    {
        if ($this->out != STDOUT) {
            parent::flush();
        }
    }
}

PHPUnit 8.5.0 by Sebastian Bergmann and contributors.
PHP Fatal error: Uncaught Cannot modify header information - headers already sent by (output started at phar:///usr/local/bin/phpunit/phpunit/Util/Printer.php:99)

ah sorry.. --stderr slove my problem

I experienced this issue when my controller was redirected to a login page.

Fixed using @victorbstan solution:

bin/phpunit --stderr

I got the same issue when testing a download file request.
Works for me too after adding the parameter.
Amazing!

Was this page helpful?
0 / 5 - 0 ratings