Cannot send session cookie - headers already sent PHPUnit / Laravel

I have this strange problem when i call the parent::setUp() on my TestCase class for unit test a class when i run phpunit it throw me this error:

1) MatchRequestRepositoryTest::test_find_requests_by_match_id ErrorException: session_start(): Cannot send session cookie - headers already sent by (output started at /var/www/project.dev/vendor/phpunit/phpunit/PHPUnit/TextUI/TestRunner.php:459)

What can be the problem? Thanks for any help.

(UPDATE: Thanks to comment by Louis Charette, this will only work in php 7.1 and earlier (and reading the bug report, it sounds like a regression they don't intend to fix. The better solution is therefore Jeff Puckett's (https://stackoverflow.com/a/38045422/841830), of giving the --stderr flag on the commandline to phpunit. This keeps stdout for your code, stderr for phpunit, and so they don't clash.)


The problem is that you have some code, perhaps deep in the framework you use, that calls session_start(). That, in turn, wants to send a cookie. But PHPUnit has already started writing output to stdout.

The point to understand here is that this is just a unit test, no-one cares about the header. So just suppress the error message. And the way you do that, without altering the system-under-test, is to call session_start() in your own unit test (either before parent::setUp() or inside that setUp function). And use the @ prefix to suppress errors. e.g.

function setUp() {
  @session_start();
  parent::setUp();
  ...
}

"headers already sent" problem in isolated tests when running with , Skipping tests that are failing due to Travis CI upgrading to PHPUnit 4. … Cannot modify header information - headers already sent by (output In my code I use the session, but not the headers if this matters. I am having the same issue like it's described here: Maatwebsite/Laravel-Excel/issues/511  @IvanChepurnyi I agree with @jzahedieh here that directing to stderr is not ideal, but the solution he's provided is not ideal either. IMO it is a better approach though, and it might be nice to see those silencers added to the setUp() and tearDown() ( @session_write_close() ) higher up the chain in the EcomDev module than individual tests?

One way to handle this in PHPUnit is to send output to stderr instead of stdout as is demonstrated by this answer.

phpunit --stderr

Or by adding stderr="true" in your phpunit.xml as is pointed out in this comment.

PhpSession messing up with tests? · Issue #12 · antonioribeiro , After upgrading to Laravel 5.4 running phpunit outputs the error below. There was 1 Cannot send session cookie - headers already sent by (output started at Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at C:\file\secret\index.php:1) in C:\anotherfile\file\index.php on line 1 Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\files\morefiles\index

In Laravel I avoided the issue by checking the environment and avoiding problematic code for 'testing' environment.

// Code working in Laravel 4.2
if(App::environment() != 'testing') {
        // this will be skipped when testing
        setcookie('key', $val, time() + (86400 * 999), '/');
}

NOTE - Warning: this means you cannot test this piece of code!

Cannot send session cookie, Hi guys, I have this strange problem when i call the parent::setUp() on my TestCase class for unit test a class. when i run phpunit it throw me this  Skipping tests that are failing due to Travis CI upgrading to PHPUnit 4. Loading status checks…. 65d4966. These tests would set headers, and in PHPUnit 3.7 running them in a separate process would allow the headers to be set, but in PHPUnit 4 this is no longer the case. This may be fixed in PHPUnit 4.0.19.

Headers already sent what's up PHPUnit?, headers already sent by (output started at So you need to include a session_start() before PHPUnit is executed. with chapters ranging from explaining how to secure HTTP cookies with the right flags to understanding why​  Headers are sent by the library code triggered by the code I test, so I cannot modify that part. And the issue is happening even if I use output buffering for the whole test. Its similar to the example here: http://stackoverflow.com/questions/9745080/test-php-headers-with-phpunit.

php - Cannot send session cookie, perhaps deep in the framework you use, that calls session_start(). That in turn wants to send a cookie. But PHPUnit has already started writing output to stdout. How to test session and cookie without encapsulate their operation in Session/Cookie class ? This is actually what you should be doing. If for whatever reason that's not possible, you can also try one of the follow: Use process isolation. Use the --stderr CLI option. Use something like uopz to mock out setcookie(). Use phpunit-selenium. 👍

Warning: session_start(): Cannot send session cookie, Hi, I am getting these errors : Warning: session_start(): Cannot send session cookie - headers already sent by (output started at  PHPUnit is running with the array session driver which seems to be overlooked by the if statement above. Running session_start() seems to request the array session driver which is already running the laravel session.

Comments
  • Please check this : stackoverflow.com/questions/8028957/…
  • You'll have to share the contents of your test. Also, is your application doing any direct manipulation of sessions, either via native session_ function calls or Session::?
  • Possible duplicate of Test PHP headers with PHPunit
  • Unfortunately, this solution will still produce an error for your test. It will produce something like this: There was 1 error: 1) Classname::ClassTest A session had already been started - ignoring session_start()
  • @w00tland The @ should stop any errors or warnings being reported. Do you have the @ on the line it is complaining about? And does adding/removing the @ change the error message? (If you cannot get the message to go away, it might be worth starting a new question; this one was about how to get rid of the "headers already sent" complaint.)
  • I know it should prevent warnings from being reported. The message I shared above is the result of suppressing the message. And yes, I get the Cannot send session cookie - headers already sent by message if I remove the @. And I have the exact same problem; I'm just trying to get rid of the "headers already sent" message.
  • For people finding this though Google, this fix might produce another set of errors with PHP 7.2 in relation with session_set_save_handler. See : bugs.php.net/bug.php?id=75628 Jeff Puckett answer is a better solution in relation to PHP 7.2 change.
  • @LouisCharette Thanks. I've updated the answer with that info.
  • is there any backfire using this? or no problem at all? thanks
  • @Carlos I still haven't found any problem with it.
  • This should be the best answer!
  • I know this is an old thread, but the problem i have on this solution is that it does not generate a junit.xml file from phpunit.xml for my unit test. I guess it is because it outputs to stderr instead of stdout.
  • @xCHAN that's an interesting caveat! I'd never thought about that side effect. You should post a solution if you discover a better option and ping me when you do.