Tuesday, April 26, 2011

Unit testing PHP with PHPUnit and runkit

Debugging PHP applications in Netbeans is one of the coolest things I've been doing in my php projects lately. I've been itching for a good TDD strategy though, and it turns out that Netbeans has pretty good PHPUnit integration with coverage tools to boot.

The issue I noticed many people have with PHPUnit is that it will not behave nicely when working with session data like sending headers and such. There are lots of posts on the internet about calling session_start() from a bootstrap before running each test, and that certainly is a good start. However, that doesn't help when a call to header() stops the test because it doesn't work.

Solution:
Using PHP runkit, we can change the functionality of the header function - as well as any other function - at runtime. This way you can print out the header to the console during testing. I added a function called myecho (echo and print are not functions so you will have to write a wrapper) and used runkit_function_remove to get rid of header, and runkit_function_copy to put myecho in its place.

The runkit framework is really useful for mocking built-in functions and other things. After playing with runkit I also found a lesser used strategy which is to redefine functions within your namespace and use the namespace separator ( \ ) operator to access things from the global scope in php 5.3. If you are on an earlier version you might as well use runkit. I read about it here: http://www.dhmedia.com.au/blogs/php5s-new-namespace-separator-backslash


Extra:
Testing applications such as RESTful services that rely on headers to send accept/content-type fields is difficult under PHPUnit since you can't just clear your session and start again during tests within a single test class. In my framework I made a test class for each mime type that I would support, namely xml, json, and plain text. For example, I would have a GetRequestTestXML and a GetRequestTestJSON class. This way the bootstrap gets loaded for each time I want to set session data like header content-types.

Monday, April 25, 2011

Hello

Hello internet,

I've been lurking around for long enough, picking up little bits of knowledge and learning from real hackers (http://en.wikipedia.org/wiki/Hacker_(programmer_subculture) ) on the internet. I, like many others out there, love programming. I don't mind battling with strange and unusual architectures. In fact, I live for those moments. I'm not offering a new programming language or any fantastic new framework or anything large scale, but hopefully some of the things that I haven't been able to find solutions for on Google's search engine will assist some other poor programmer out there. With that said, I wish us both good luck and look forward to some interesting times!