Unit testing is one of the practical facets of eXtreme programming. As a PHP developer just the concept on having some kind of system for testing may get the hacker in you screaming rebellion.
In this article I’ll look at a script which makes unit testing a pleasure rather than a burden.
eXtreme programming, even by it’s name, is a controversial subject.
Is it some kind of methodology for programming while sky diving?
Alot of what eXtreme programming advocates is “how to work” like
coding in pairs. One aspect though which applies directly to code
itself is unit testing.
In general the “testing lifecycle” of software is summarized as;
unit testing: testing each “piece” of code
system or integration testing: testing the code within the type of environment it will work in
acceptance testing: testing the application from a user point of view
Now for your typical PHP
project, testing is probably ad hoc, if at all, which is understandable
with a language where you can build an “app” a user can begin working
with in a matter of minutes.
But if the expiry date of the code we’re working on is longer than
24 hours, chances are we’ll end up writing something far bigger than we
originally planned and start having to spend more and more time on
debugging and testing code that wasn’t that well designed in the first
place.
This is where unit testing can be a real help. The basic
concept of unit testing is write more code which will test the main
code we’ve written, by “throwing” sample data at it and examining what
it gets back.
On reading “more code” you may be starting to lose interest but in
general, writing test scripts is very little work and the good news is
once they’re written, you can retest your code ad infinitum with
nothing more than the click of a mouse. A change “here” may effect code
we couldn’t have imagined - re-running a black box test tells us
everything is still working properly.
There are two approaches to unit testing: black box testing (which is what we’ll be looking at here) and while box testing.
Black box testing takes the approach of working outside
the code being tested (hence the code is a black box), passing data to
it and examining what it gets back. This approach is particularily
useful for classes where we’ve got a well designed API. It also means we don’t have to “mess” with the code we’re testing so generally less work.
White box testing takes the view that everything can ( and perhaps
should ) be tested (no hiding behind APIs) and generally means adding
the tests directly to the code being tested. In some cases it’s
essential - a class method may return the correct value but some
operation it performed “behind the scenes” has gone badly wrong. To
some degree we’ve all used white box testing when using print
statements inside a class to find out what’s going on.
In a perfect world, given infinite time and interest, we should
probably use both to the fullest extent. Just using black box testing
though is a good start and meets the practical constraint effecting
most developers: lack of time.
One final piece of introduction: eXtreme programming suggests writing the tests before the code they’ll be testing.
From a developers perspectice, it takes some getting used to but,
daring to intepret the intent of this practice, it’s meant to encourage
developers to focus on designing a solid API.
In general this has much in parallel with code that starts out as UML
and isn’t such a far cry from what most developers probably do in their
head anyway.
Enough theory. Now to make good the claim that unit testing (black box at least) is both easy and fast to implement.
There are quite a few PHP
projects out there offering unit testing environments, which are all
(hopefully) listed at the end of this article, all of which are
projects approaching Java’s http://www.junit.org/ - JUnit . PHP also has an http://www.php.net/assert - assert() function which can be useful with procedural code but hamstrings itself by relying on a callback function to respond to exceptions.
In this article we’ll be using http://www.students.cs.uu.nl/people/voostind/index.php?page=software - PHPUnit from Vincent Oostindië, author of the http://www.students.cs.uu.nl/people/voostind/eclipse/ - Eclipse Library (which is well worth checking out by the way). It’s provided with the code for this article.
This particular PHPUnit is a single script which is lightweight and extremely easy to use. Some would argue this is exactly what a unit testing tool should be like.
Now a while back we looked at the http://www.phppatterns.com/docs/design/strategy_pattern - Strategy Pattern .
Using Vincent’s PHPUnit (which is well documented by the way - just
point your browser at it and all will be revealed), the first thing is
to create a sub directory “test” which will contain all the test
scripts and PHPUnit itself (in the same code it’s renamed to index.php
for convienience).
Taking one class in particular to illustrate how the test scripts
are written, lets test the ValidateUser class (from the strategy
pattern article).
The basic “rules” of Vincents test environment are;
<list> Create one test class per test script, the class name
being the same as the file name. All methods within the test class
beginning with the letters “test” will be executed by PHPUnit All test
classes must extend a class Test The test scripts need to include the
script they will be testing (obviously).</list>