PHPUnit Essentials Book Review

PHPUnit Essentials would have come in handy while on a recent contracting gig and on all the other PHP projects I’ve worked on. The book is published by Packt Publishing, the last book I bought from them was on AngularJS and it was a great guide whereas as the O’Reilly book on AngularJS was outdated.

Overall the book was a good read and it’s worth getting as both a guide and a reference.

Installation and IDE Support

The book is great in covering multiple installation methods and multiple IDEs. You can install PHPUnit using Composer, PEAR, through a
Linux package or through manual installation. According to the book, PHPUnit support can be found in the NetBeans, Zend Studio, Eclipse PDT and PHPStorm IDEs which is really great since I’ve using Intellij and PyCharm. This kind of coverage is awesome because every single PHP project is different; some developers like Zend Studio, others use VIM, some developers use PEAR while others use Composer.

I liked how much detail the book went into about each method of install, for example I haven’t used Composer on a project yet but seeing how simple it is in this chapter, I’m going to consider its use on future PHP projects.

Unit testing and assertions

Chapter 3 covers what a unit test is, and how to define them using PHPUnit. One thing I didn’t like about this chapter is that it refers you to a URL to see a complete list of assertions you can use in tests. It would be nice if the complete list was shoved into the back as an appendix so that it could be used as a quick reference.

Testing errors and exceptions

In chapter 4, the book covers how to test errors and exceptions and while this is useful, it feels like a section that could have been expanded on further. There’s only one example and the code doesn’t show the specific code that’s replaced by the annotation.

Running tests

Chapter 5 was surprisingly useful because it gives a good overview of the output of running phpunit and the command-line options available. When you’re a complete beginner, this is invaluable, even for experts it’s a handy reference.

Testing External APIs

An interesting real-world example that frequently comes up is how to test code that uses external APIs. PHPUnit Essentials covers this in chapter 10 with examples of integration with the Stackoverflow, the Paypal, the Facebook and the Twitter APIs. While the book covers publicly available APIs, the code examples are solid guide on how to test proprietary external APIs as well.

The only criticism I would offer of this section is that maybe it tests too many external APIs at once. Sacrificing this chapter to add more information on writing custom assertions or on how to test with legacy code might would have been a good idea.

Testing Legacy Code

The spaghetti code, the ugly legacy code that every programmer in their career has to maintain at least once. PHPUnit Essentials covers how to test legacy code quite well and in an unexpected way. It suggests first using Selenium and integration tests to cover the overall interactions in the code rather than unit testing to cover specific methods. In a disorganized codebase there could easily be thousands of methods and writing unit tests for each one would take up a lot of time. Writing integration tests for core functionality takes much less time.

One unexpected way of testing is to use reflection. According to the book, “reflection is defined as the ability to inspect and modify code at runtime”. It highlights that final, private/protected and static methods cannot be tested easily but in a legacy codebase you may want to test them (some ugly code is hidden by declaring it as a private/protected method).

The other unexpected surprise is the section on dealing with dependencies in legacy code. The author uses WordPress as an example of legacy code! While this is true, it’s a little crazy (and awesome) to actually call out a very popular framework and treat it as legacy code. The section details the Patchwork, vfsStream and runkit libraries. Most web developers never ever use those libraries and the author does a great service to the community and to legacy code maintainers by introducing these tools.

The WordPress example uses mock objects and the Patchwork library to replace a method and make it easily testable. The vfsStream mock file system library is used in an example of CSV data exporting and I like this choice since this is a common and real-world occurrence and you need to be able to test filesystem access. The WordPress example is again used in conjunction with the runkit library (which the author helpfully notes you need to compile using PECL).

Code examples

The source code in the book is nice and clear. The drawback of it are the comments. For example in chapter 4 on pages 68 to 71, the source code includes Javadoc-style comments that mirror the name of the methods: the createUser method is preceded by a comment stating “stores user to the database”, the comment for the sendActivationEmail method reads “sends activation email”.

What was also nice was the use of PHP namespaces. PHP namespaces are a relatively new feature introduced in PHP 5.3.0 and the last few PHP projects I’ve been on neglected to use them; seeing a real code example that uses them makes it more likely that I’ll use namespaces in the future.

Another drawback of the code is that sometimes external code is referred to by URLs and those URLs may stop working one day. If an example is relying on external code, it’d be nice if there were a copy made of it and added to the PacktPub website somewhere or if some of the links were more permanent; for example the GitHub source code links where the source code is liable to change daily or weekly (the WordPress example in chapter 11 springs to mind here).

Conclusion

The book nicely progresses so that you’re building up your knowledge after each chapter. By chapter 7 you’re able to write unit tests for a project that’s in production. After chapters 8, 9 and 10, you’re ready to add integration tests on top of your unit tests to ensure your project co-operates with databases and external APIs. Chapter 11 “Testing Legacy Code” is a gem that will serve any maintenance developers well.

The code examples are well written and follow a nice easy to read style. Removing the redundant comments would shorten the code and make it even more readable.

Definitely would recommend this to anyone who’s working on a PHP web app. Buy the book now, and save yourself from PHP unit testing frustration: PHPUnit Essentials