phpunit Test error :headers already sent by ..... Printer.php:173

Hello together

I'm looking everywhere, but didn't find a working solution!

The "problem":
I use phpunit-Test with phpStorm. In this one of my TestClasses, on one line I have to set cookie-value. And I'm sure this is the main-problem. The error is

PHPUnit_Framework_Error_Warning : Cannot modify header information - headers already sent by (output started at /Applications/MAMP/bin/php/php5.3.6/lib/php/PHPUnit/Util/Printer.php:173) #0 [internal function]: PHPUnit_Util_ErrorHandler::handleError(2, 'Cannot modify h...', '/Applications/M...', 1046, Array) #1 /Applications/MAMP/htdocs/yii-1.1.9.r3527/framework/web/CHttpRequest.php(1046): setcookie('_selectedLang', 'en_us', 1340444026, '/', '', false, false)




So I try to find a solution with the help of phpunit forums. And there are a few developers with the same problem. Somewhere I found a solution with the command-line option "--stderr". So in the terminal the same phpunit-Test is running without error and it gave the expected response with all the test-results from the method.

BUT, if I try to set the same option in the Run/Debug Configurations for the MLocaleManagerTest in phpStorm if I try under Command Line Interpreter options: The result is NO TEST => Process finished with exit code 0.
If I try under Test Runner > Test Runner options: there is the same unlike error " Cannot modify header information blablabla".

So what can I do for use the TestClassMethod in phpStorm with the same result like in Terminal-App with the option  "--stderr".
I found an other solution with set the function ob_start() in the bootstrap, but this isn't work for Terminal nor phpStorm.

Did someone have the same problems in the past and found a working solution. It would be great to hear about.
I lost so much of time....

Kind regards
Martin

8 comments
Comment actions Permalink

Hi there,

PhpStorm does not support --stderr option. Please vote/comment/watch this ticket: http://youtrack.jetbrains.com/issue/WI-8994

The only option you can do is to use some wrappers (functions or classes) instead of calling header/set_cookie etc functions directly (or, at very least, try prepend such statements with error-suppression @ character; surround with condition that checks headers_send() result etc).

You may look at implementing your own TestSuite class, which will alllow to execute some code much sooner, before PHPUnit will print any header text (e.g. version info), but I'm not sure about this at all.

0
Comment actions Permalink

Andriy,

Thanks for assistance!:)

0
Comment actions Permalink

Hi Andriy,
thanks for your help. At least, I don't have to search an solution with other command-line options or something like this.
Unfortunatelly, my tickets in youtrack don't have the best response X-(. The last two were closed (will not include, or something like this....).But I will hope, maybe there are miracles:). But I think with 3 + in a half year, the chances are really small sized. But who knows.

The line <citation> our test runner UI based on the console output</citation> sounds not really good. So what! I have to work around with divide the tests in tests for terminal and tests for phpStorm internal. Shit happens, but I think your other ideas doesn't get me a practicle solution. First my scills in phpunit are not really good, and I doesn't find something in the web about this points...

Maybe an other developer have a good idea, or a solution because he had the same problem.
Thanks anyway

Martin

only seconds after my post :Wouw, thanks for your help in http://youtrack.jetbrains.com/issue/WI-8994 Maybe I will find a solution on this track.

<citation>In your case you can write your own cookie handler class and use it instead of actual CHttpCookie in your tests only – that's one of the solutions advised on PHPUnit manual pages (your class will not set real cookies, but will handle them internally, which is perfectly fine for unit testing).

AFAIK Yiii framework allows you to replace standard Yii class with your own implementation.
</citation>

0
Comment actions Permalink

@Martin
In your case you can write your own cookie handler class and use it instead of actual CHttpCookie in your tests only -- that's one of the solutions advised on PHPUnit manual pages (your class will not set real cookies, but will handle them internally, which is perfectly fine for unit testing).

AFAIK Yii framework allows you to replace standard Yii class with your own implementation:

0
Comment actions Permalink

mad99,

Unfortunatelly, my tickets in youtrack don't have the best response X-(. The last two were closed (will not include, or something like this....).

I am pretty sure that there were some reasons for that. If you provide me the links I will look at them.

Thank you for feedback!

0
Comment actions Permalink

Hy Andriy,
thank you for your hint. Because of this, now I have a working solution. Maybe toooo quick and durty, but till yet it works!!
And maybe someone-else is happy about, to find a solution, or a hint in the right direction. So I share the code at this place.

It's only for yii-user, but I'm sure, with other frameworks the idea works also fine with different code.
The "problem-function" was setcookie() in CHttp::addCookie().
So my class-method check if the request is from phpunit. If so, it fill up the property _cookies with a instance of MCookieCollection instead of CCookieCollection.
The method MCookieCollection::addCookie() ist the realy durty-part.
It set the global-variable $_COOKIE direct, no "problem-function" used.It works fine without to much of code, and phpunit-Test deliver the same result like in comment-line.
The constant YII_DEBUG make sure to use the CHttpRequest::getCookies() if the project is online (YII_DEBUG false),
!!! but for this you have to set this constant in the bootstrap.php File in the phpunit envirement. !!!

The public property $phpUnitScriptName can set in the config-file (main.php) with different strings. like "phpunit" for command-line and "ide-phpunit.php" with phpStorm. But "phpunit" catch both of them....

So first the MHttpRequest.php file:

class MHttpRequest extends CHttpRequest {     public $phpUnitScriptName='phpunit';     protected $_cookies;     public function getCookies()     {         if(YII_DEBUG && strpos(             substr(($file=Yii::app()->getRequest()->getScriptFile())             ,strrpos($file,'/')+1), $this->phpUnitScriptName) !== false)                 return $this->_cookies=new MCookieCollection($this);         else             return parent::getCookies();     } } class MCookieCollection extends CCookieCollection {     function addCookie($cookie)     {         $_COOKIE[$cookie->name]=$cookie->value;     } }



second the part in main.php

'components'=>array(         'request'=>array(             'class'=>'application.components.MHttpRequest',             'phpUnitScriptName'=>'phpunit',         ),



All the best
Martin

0
Comment actions Permalink

Hi Nicolay,
no worry about, I thought my feature-requests were not important enogh, not wished, or they need to much developers-time for the "small effort".
The second smilie was the more important one in my post ahead ( :)), not the AngrySmilie...

But you will get an answer on your question the links are:
http://youtrack.jetbrains.com/issue/WI-11352
http://youtrack.jetbrains.com/issue/IDEABKL-6362

I loved the short look up, for php-manual in zendStudio but more than I hated all the drawbacks from ZS. I'm really happy with phpStorm. So I can do a work around.

The labeling would be nice, but I understand the argument from Dmitry Jemerov. No problem! Would be a really nice feature in my oppinion, but without, the world will turn around ;).

Kind regards
Martin

0
Comment actions Permalink

mad99,

Please look at the workaround suggested by our user - http://youtrack.jetbrains.com/issue/WI-8994#comment=27-346846.

Thank you for feedback!

0

Please sign in to leave a comment.