On Tue, Mar 17, 2009 at 7:25 PM, Matthew Weier O'Phinney
<[email protected]> wrote:
> -- till <[email protected]> wrote
> (on Tuesday, 17 March 2009, 05:21 PM +0100):
>> trying to wrap my head around Zend_Test, here are some things I can't
>> figure out:
>>
>> 1) My app uses setRawHeader(), header() etc. -- for example, inside my
>> error controller, or in my index.php to "send" a P3P policy. They all
>> fail with similar errors:
>>
>> testIfHomeExists(RestControllerTest)
>> Cannot modify header information - headers already sent by (output
>> started at /usr/local/share/pear/PHPUnit/Util/Printer.php:168)
>> /path/www/index.php:23
>>
>> Line 23 is a header('...'); call.
>
> Use the response object to set all headers; it's the only way to
> guarantee all headers are sent at the appropriate time -- and in CLI
> environments (such as unit tests), ensure that no errors are thrown due
> to lack of headers in the environment. Unfortunately, there's no way
> around this -- header() is very unfriendly to the CLI environment.
Yeah, I figured that out last night, so I moved the calls (for
content-type and p3p) from index.php into my bootstrap and got
slightly further (see below).
The other thing I noticed was that it did in my ErrorController too (I
tested it -- e.g. url does not exist, assert the status code is 404),
but I am using setRawHeader() there.
I'll give you a hopefully more detailed example:
/**
* Renders the response
*
* @param Zend_Controller_Response_Abstract $response - The response object
* @return void
*/
public function render(Zend_Controller_Response_Abstract $response)
{
$response->setHeader('Content-Type', 'text/html; charset=utf-8', true);
$response->setHeader('P3P', 'policyref="/w3c/p3p.xml",CP="NOI
DSP COR NID CURi DEVa OUR NOR"', true);
$response->sendHeaders();
$response->outputBody();
}
My test dies:
1) testIfHomeExists(RestControllerTest)
Zend_Controller_Response_Exception: Cannot send headers; headers
already sent in /usr/local/share/pear/PHPUnit/Util/Printer.php, line
168
/path/library/Zend/Controller/Response/Abstract.php:281
/path/library/Zend/Controller/Response/Abstract.php:114
/path/bootstrap.php:615
/path/bootstrap.php:144
/path/www/index.php:26
/path/library/Zend/Test/PHPUnit/ControllerTestCase.php:129
/path/Zend/Test/PHPUnit/ControllerTestCase.php:106
/path/tests/controller/RestControllerTest.php:17
615 is the first $response->setHeader() from above.
This is my test:
public function testIfHomeExists()
{
$this->dispatch('/');
$this->assertModule('default');
$this->assertController('index');
$this->assertAction('index');
}
Fairly simple.
>> 2) My www/index.php kinda looks like this:
>> $app = new Bootstrap('environenment');
>> $app->start();
>>
>> Now, I thought I could duplicate this in my tests like this:
>>
>> ...
>> public function setUp()
>> {
>> $bootstrap = new Bootstrap('testing');
>> $this->bootstrap = array($bootstrap, 'start');
>> }
>>
>> ... but to no avail. Whenever I do that, it returns the "entire" html
>> of my frontpage, before anything happens. I'm not ruling out that it's
>> my fault of course, but I also don't know how to debug this further.
>
> After you set that, call:
>
> parent::setUp();
>
> Otherwise, it won't bootstrap properly. :-) (This *is* documented and
> shown in the examples.)
Yeah, sorry -- I got that but I forgot to add it here. ;-( Btw,
whenever I use $this->bootstrap($bootstrap, 'start') I get the entire
homepage's HTML, when I use $this->bootstrap = '/path/www/index.php';
I get further.
Using the 'index.php' I use my 'staging' environment vs. 'testing'
otherwise, but I haven't been able to verify why it wouldn't work. I
omit a couple configuration steps with testing, for example, I don't
use my DB handler for sessions, etc.. Nothing major. I'll debug this
later once I figured out the headers.
I could show you some code off list, if that helps.
>> I can't share much code, unfortunately, but does anyone have any ideas?
>>
>> In general, is Zend_Test ready for "production" yet? I think I pretty
>> much run into everything that's still being worked on -- e.g.
>> Zend_Session (static issues), cookie-related, etc.. So far, I'm
>> pondering to write "regular" unit tests which would involve getting
>> the pages through a http client and then parsing them with DOM
>> methods.
>
> It's production ready -- I've been using it a ton. The principal issues
> lie in the framework itself. For instance, we need to add cookie support
> in the response object, and Zend_Session needs to be refactored to make
> it easier to test against.
I've discovered the Zend_Session::$_unitTestEnabled flag, but why I am
asking is, that, e.g. my tearDown() looks like this:
public function tearDown()
{
Zend_Session::namespaceUnset('fooSession');
Zend_Session::expireSessionCookie();
Zend_Session::stop();
Zend_Session::destroy(true);
unset($this->bootstrap);
}
Yet, all consecutive tests fail because it says:
Zend_Session_Exception: A session namespace object already exists for
this namespace ('fooSession'), and no additional accessors (session
namespace objects) for this namespace are permitted.
I'm opening fooSession in my bootstrap, but from what I gather my
tearDown() doesn't get rid off everything.
That's another thing I've been wrestling with. ;-)
I've researched (aka googled) this a bit and found a couple threads
and issues related to Zend_Session and Zend_Test, but I never
understood why people claim that sessions limited or hard to test on
the CLI in general -- I think you can test this just fine, just check
this for an example:
<http://cvs.php.net/viewvc.cgi/pear/HTTP_Session2/tests/test-session.phpt?revision=1.1&view=markup>
Thanks for your help,
Till