Adding PHPUnit to your project (Simple)
So far we have worked through some very simple examples involving just a single file that we are testing. In reality, most projects include many different classes and should include many different tests. One of the keys to a successful test strategy for any project is organization of these classes and tests.
Getting ready...
A common strategy for test organizations is separating tests from source code using the directory structure of the projects. A very easy way to do this is by placing a src
and test
directory at the root of your project. The src
directory would contain all of the code required to run your program. Then the test
directory can contain code that is required to test your program. Within these two directories you can have nearly identical file layouts with the sole exception being the Test
suffix on the test case class and the Test.php
suffix on the file.
We will now go through an example of how this type of structure can be set up and utilized in your project.
How to do it…
In your project, move your files into the following structure:
Then, create a
test-bootstrap.php
file with the following content:<?php spl_autoload_register(function ($className) { $classPath = str_replace( array('_', '\\'), DIRECTORY_SEPARATOR, $className ) . '.php'; require $classPath; });
Next, modify your
phpunit.xml
file to contain the following code:<phpunit bootstrap="test-bootstrap.php" colors="false" strict="true" verbose="true" > <testsuites> <testsuite name="Go Fish Test Suite"> <directory suffix="Test.php">test</directory> </testsuite> </testsuites> <php> <includePath>src</includePath> </php> </phpunit>
Finally, remove the
require
statement that is intest/CardTest.php
.
How it works…
Here we are introduced to another feature in PHPUnit: the bootstrap file. The bootstrap file is run by phpunit
prior to running any tests. This makes it a very convenient place to set up our environment as a whole for testability. This could be anything from setting configurations to setting up an autoloader. We have used it for the latter.
In our test-bootstrap.php
file we have added a call to spl_autoload_register()
to look for any files in our include_path
where the path is the same as the class name after all underscores and namespace separators are replaced with a DIRECTORY_SEPARATOR
constant and the .php
file extension is added. This is a subset of the PSR-0 standard: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md.
Once our bootstrap file is created we must make PHPUnit aware of the file. To do this you can use the bootstrap
attribute of the <phpunit>
element. We also need to set the include path. You can see we have done that using the <php>
and <includePath>
elements.
With all of this set up, we can now remove the require
statements from our test and everything will continue to run normally.
This helps us further meet the goal of making it easy to write tests. We no longer have to maintain file dependencies ourselves. It is all handled for us by virtue of our autoloader and bootstrap. So adding a test is really just a simple matter of creating the test case.
There's more...
Some parts of this recipe should not necessarily be followed verbatim. For instance, there is really little reason to roll your own autoloader. You, most likely, already have an autoloader defined for your project. If you don't have one defined there are several libraries already built that all handle the PSR-0 standard. One such library is the Symfony2 ClassLoader Component: http://symfony.com/doc/current/components/class_loader.html. If you are using Composer then you can also take advantage of its autoloader: http://getcomposer.org/doc/01-basic-usage.md#autoloading.