I haven’t written here for ages. Things have been slightly quiet on the interesting work front and life has also got in the way. Anyway, I recently started work on some larger projects and have a few ideas on what to blog about from that. One of the projects is making heavy use of PHPExcel and I hope to write some more about that in the next few weeks. I’ve also recently started writing unit tests for my code using PHPUnit. I’m still a relative newb at writing unit tests but thought I’d write a short post about my experience of working with PHPUnit for the last few weeks.
What is PHPUnit?
PHPUnit is an xUnit implementation in PHP. It’s a framework that allows us to create tests for our classes as we write them, eventually building up a test suite for a group of classes or a project. This allows us to work in a manner described as Test Driven Development (TDD) where code and the test cases to test it are developed concurrently (often the tests are written first). This method of development confers many important advantages:
- As tests are written incrementally as you write a class it’s possible to catch bugs as you write the class in many cases by running the tests against the code that has been completed.
- Often objects have to be ‘plugged into’ many other objects as part of an application. By waiting until all of the components of an application are written before testing code debugging becomes much harder. Unit testing allows us to test how objects perform before they are integrated into an application making it possible to catch and eliminate bugs much more easily and sooner in the development process.
- Changes to a class can often lead to difficult to track down bugs since changes can potentially affect how objects interact with each other. Having a unit test for a class helps to make this process far more efficient. If after making changes to a class the code still passes all of its tests you can be fairly sure that that changes haven’t broken anything. At the worst test failures alert you to potential problem areas in the code before you try to run the application.
I first became aware of TDD and unit testing about a year ago on first reading ‘php|architect’s Guide to PHP Design Patterns‘ and I’ve been wanting to integrate unit tests into my work flow for a while. I’m very glad that I did!
PHPUnit is best installed using PEAR and full instructions can be found on their website. I came across a couple of small issues that held me up for a while. Firstly PHPUnit was complaining about the version of PEAR that I had installed (I’m running PHP 5.3.3 on Windows for development). After rooting around for a while I found the solution was to issue the command ‘pear upgrade pear’ from the command line. This upgraded the pear installer to the latest version, which allowed me to install PHPUnit once all of the channels it depends on were added. I also ran into some problems with running PHPUnit from the command line. I hadn’t added the PEAR directory to my system path and once I had done that running unit tests became very easy.
Writing Your First Test
There’s excellent documentation on the PHPUnit website but I’ll write briefly about the process here. PHPUnit tests are classes that extend (in most cases) PHPUnit_Framework_TestCase. The methods in the class that contain the tests must be public and the method names must start with the word ‘test’ (PHPUnit must be using Reflection to find the methods to call). The test methods will call various methods on the class to be tested and can then assert that various conditions are being met. These can test that the return value of a method equals an expected value, is an expected data type, and many others. By writing a number of test methods it’s possible to test all aspects of your class. There’s far more to go into than I’ve written here. It’s possible to create mock objects that mock dependencies (such as database connections or file handles) to simplify the creation of tests and PHPUnit gives you many methods to test all aspects of the objects under test. The important thing is that PHPUnit gives you the power to write fully comprehensive tests.
Running Your Tests
Running your tests is easy. Providing the path to your PEAR directory is in your system path it’s simply a matter of typing ‘phpunit path\to\your\test’ at the command line. The final part of the path should just be the name of the test class. PHPUnit will then run all of the tests in your unit test and for each test passed will print a ‘.’ on the command line. For test failures a ‘F’ is printed and for errors a ‘E’ is printed. Naturally, full details of the problems are also printed. One nice feature is the ability to run multiple tests in one command. Providing each of your test classes include the word ‘Test’ (with a capital T) in their names you just need to supply the path to the directory containing the test cases at the command line. PHPUnit will then run all of the tests in your suite in one go.
I’m obviously at the beginning of writing good unit tests and I’d appreciate any thoughts ot comments that others may have. I need to read the PHPUnit documentation in far more detail but what are some of the ‘best practices’ in unit testing? Can anyone recommend any good articles on writing tests? I’d love to read any comments and suggestions others may have.