This is Part I of a multi-part series. Below are the links to other
parts of this tutorial!
For months now I have been telling myself I would create an in-depth, multi-part
series of articles that would take a developer from being a complete newbie at
testing to have them mocking classes left and right and asserting until the break of
This series will introduce you to the core concepts of testing. It will tell you why
statics are bad, why dependency injection is king, what the difference between a mock
and a stub is and how to love the red and green bar.
I will lightly touch on test-driven development but will not focus on it as I
believe writing your code to be testable and learning how to actually test is a big
enough challenge to learn at first without throwing in a completely different method
to your development process. Baby steps is the name of the game.
What this series will not go over is why you should test, why testing is good and
the benefits of testing, other than a slight glossing over.
If you would like to be serenaded with the virtues of testing then I recommend you
check out the book
Real-World Solutions for Developing High-Quality PHP Frameworks and Applications
by Sebastian Bergmann and check out my buddy
Chris Hartjes, The Grumpy Programmer’s blog.
Chris has been screaming at the PHP community for years that they should test. He
is now holding classes to teach you some knowledge and I wholeheartedly recommend you
take a good look.
BEFORE YOU BEGIN
This series will assume you have a proper development environment set up. I highly
recommend using a VM that mimics a server environment instead of having your server
running alongside your daily OS. If you do not have a proper environment set up then
I recommend you read through my
Setting Up a Debian VM, Step by Step
guide to get you up and running painlessly.
We are also going to use the command line to run … commands. If you are used to a
GUI doing everything for you, it is high time you cowboy up and got to loving the terminal.
It used to be that the recommended way of installing PHPUnit was through PEAR. Now
that Composer has come and taken the crown of package manager I suggest you go
If you do not know what Composer is or how to use it then you should read my
Composer Namespaces in 5 Minutes.
It introduces you to Composer in general and how it utilizes PSR-0 for autoloading.
All it takes to install PHPUnit is a single line in your composer.json file:
You should also install XDebug. If you are not using using Xdebug then head over to
Xdebug and You: Why You Should be Using a Real Debugger
and stop being a caveman. It is a much better alternative to trashing your codebase
var_dump and it is also required to utilize PHPUnit’s
awesome code coverage report tools!
To make Composer download your new libraries simply run
$ ./composer.phar update --dev and Composer will work its magic for you.
./vendor/bin/phpunit. This is the file you will mostly be interacting
with to run PHPUnit. It is extremely simple and to the point - all it does is look
for Composer’s autoloader and load it.
To run PHPUnit, you simply do
$ ./vendor/bin/phpunit. This will print all options
available to you.
STRUCTURING THE PROJECT
Since we are using Composer we will take some time to properly setup our project so
everything works with the autoloader. We will name the project
will use that as the namespace.
composer.json file to look like this:
Then update composer with
$ ./composer.phar update. Our project files will live
phpUnitTutorial folder, which will be on the same level as the
vendors folder. Simply create an empty folder so your folder structure looks like:
SETTING UP phpunit.xml
Running PHPUnit will go through your tests using built-in defaults. You can override
many defaults via the command line, but there is a better way: the
configuration file. Yes, yes, “Ewwww XML!”. I usually say the same thing, but this
file is fairly painless.
In the root of your project create a
phpunit.xml with the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="Application Test Suite">
This is an extremely slim, simple configuration file, but it sets two important
colors="true" makes sure your test results are in color, and
<directory>./phpUnitTutorial/Test/</directory> tells PHPUnit where your tests
will be located, so you don’t have to manually tell it every time you run your tests.
You have not created this folder, so do so now. Your file structure should look like:
All your application’s tests should go within
PHPUnit has a few conventions to make your life easier. You do not necessarily have
to follow them if you want to do things slightly differently, but for our purposes
we are going to stick to them.
File structure and filenames
The first convention we will discuss is the file structure and filenames.
Your tests should mirror your codebase directly but within its own folder, and test
files must match the file they are testing, with
Test appended. In our example, if
we had the following code:
Our tests would be structured as:
Classnames are exactly the same as filenames. Whatever you have named your file
should be the name of your class - which should be true for your non-test code
Method (test) names
Your test method names should start with
test, in lower case. Method names should
be descriptive of what is being tested, and should include the name of the method
being tested. This is not a place for short, abbreviated method names.
For example, if you are testing a method called
verifyAccount(), and in one unit
test you want to test that the password matches, you would name your test
Verbosity is a boon when testing, because when you have a failing test, and you
will have many failing tests, you will be appreciative of seeing the method name
and knowing exactly what failed.
Methods must be public
PHPUnit is unable to run tests that are either protected or private - they must be
public. Likewise, any methods you create as helpers must be public. We are not
building a public API here, we just want to write tests so do not worry about
Duh! Your classes must extend the
PHPUnit_Framework_TestCase class, or extend a
class that does.
Our first test will be short and stupid, but it will introduce to you the very
minimum required for a test.
Create a new file at
class StupidTest extends \PHPUnit_Framework_TestCase
This is nothing special - just your run of the mill class. Notice how we are already
following three conventions, though.
To get our feet wet, we want to verify that something equals true. Assertions are the
true power of PHPUnit, and I will be covering them more in upcoming parts of this
For now, create a method
testTrueIsTrue. You can already feel the stupid, right?
public function testTrueIsTrue()
Now comes the actual test code. It is as simple as it looks, so try not to
over-think what is going on:
public function testTrueIsTrue()
$foo = true;
DAT GREEN BAR
From project root, run PHPUnit:
You should see the coveted green bar:
You ran a single test file,
1 test, with a single assertion
Congratulations, you are now one step closer to joining the ranks of tester!
Today you installed PHPUnit using Composer, set up some sane defaults and even ran
your first (stupid) test.
You are now one small step closer to becoming one with the green bar! Congratulations!
I realize the first step looks useless, but it reinforces the idea that testing is
not some mythical, high-level concept that requires a PHD to understand. It really
is just telling the code, “This is what I expect to happen” and the code letting you
know if you have screwed up somewhere.
In the next part, I will explain assertions, introduce annotations including the very
dataProvider and walk you through creating your first non-trivial unit