After having gotten some constructive feedback regarding my testing practices on the basic TDD in your new PHP package tutorial, I decided to read Chris Hartjes “Grumpy Testing Bundle”, a set of two books consisting of The Grumpy Programmer’s Guide To Building Testable PHP Applications and The Grumpy Programmer’s PHPUnit Cookbook. It was my hope that those books will prevent me from using the shoddy practices I displayed in that original post and which originally prompted Matthew Weier O’Phinney’s critique. In this post, I’d like to share with you what I’ve learned, and how much this helped me, if at all.
The Grumpy Programmer’s Guide To Building Testable PHP Applications
The first thing I noticed when opening the book was the low page count. For a hefty $20, one would expect more than 68 pages (including dedication, intro, ToC, etc). One shouldn’t judge a book by its cover (or page count), though, so I dove in enthusiastically, disregarding this.
The book has a total of 15 chapters, and only really starts in chapter 7. If you just read Peter’s tutorial on code analysis tools and are familiar with environment isolation like Vagrant (e.g. our Homestead Improved box), you can skip right to it, as those are the only topics the author touches on in those first 22 pages. Unfortunately, it all goes downhill from there due to the severe outdatedness.
- the author mentions PHPUnit and its installation via PEAR, when this is no longer supported. This would confuse new readers unfamiliar with the situation. In fact, I call to all PHP authors and developers to openly dismiss PEAR as a relic of the past not to be used for any purpose whatsoever any more. If you have PEAR instructions in your blog posts or books, please, update your materials to use Composer.
- the author mentions the application we’ll be using is on OS X of a specific version, but then continues to talk about VMs and mentions Vagrant. This calls into question the necessity of even mentioning the original setup, as it’s just plain confusing to users of other operating systems, and should be entirely irrelevant if VM-powered best practices are to be advocated.
- the author makes references to issues of Vagrant instability but this is no longer the case – Vagrant has been stable and problem free for a while now, and temporary bugs shouldn’t be pointed out so prominently as they tend to lose relevancy quickly.
- at one point, the Phix project was mentioned which, at its prime, was an admirable pre-Composer guide on creating shareable components. Composer rendered it obsolete and the site will be shutting down soon, so references to it should reflect that
- some links are dead, too, like http://framework.zend.com/manual/en/zend.dom.query.html. Ignoring the fact that there are better components suited for the task of DOM traversal today, an author without an official editor and publishing house should always maintain a list of links in a given piece of published for-profit writing and keep them up to date
In the chapters that follow, the code examples are few and far inbetween, but those that are there are well constructed and help illustrate the importance of SOLID principles in developing testable apps – the main purpose of the book, of course. One gripe I have with the examples is that they aren’t sufficiently explained and often need referring to the PHPUnit docs. For example, the code:
// Create a mock object $testRequest = $this-> getMock( '\Grumpy\Request' , array( 'getUri' ) ); // Create our test response $testRequest -> expects() -> method( 'getUri' ) -> with( '/dashboard' );
… while technically sound, is not dissected. Finding out what the
with methods do requires a visit to the documentation, and this breaks the smooth reading flow and reduces confidence in people unfamiliar with PHPUnit by inducing a feeling of “Should I already understand this? Why don’t I?”
Some parts, on the other hand, are very well demonstrated and described. The particular case of mocking a Facebook Connect provider sheds some light on the concept of easy mocking and not having to depend on outside resources better than the official docs of PHPUnit do.
Like many other materials in book or conference-talk form today, SOLID principles are advocated throughout the two to three following chapters, and the vast majority of the content will be (over)familiar to you if you’re even the least bit aware of what SOLID stands for. Read Alejandro Gervasio’s absolutely amazing tutorials (I’ve yet to find better and more down-to-earth explanations of SOLID concepts than his) and another chunk of the book (and not just this book!) becomes obsolete fast.
Then comes the abrupt ending of the book. I say ending because the chapters become republished blog posts starting with chapter 9. A book that was last updated in 2013 and originally published in 2012 must not quote unaltered resources 5-6 years old. That’s simply unacceptable:
- with the advent of tools like http://psysh.org/, chapter 9, a copy of this 5 year old blog post, seems obsolete.
- chapter 10 is a copy of this old blog post. Its relevance in this book is questionable.
- chapter 11 is a repost of this post which is, again, 5 years old and completely obsolete. For up to date CI solutions in the PHP world, just refer to these tutorials.
- chapter 12, another repost of a blog post I could not find, talks about infrastructure debt – the art of moving away from personal dev environments and into VM waters for unified environments for the entire team. This topic has been mentioned in a shorter and more effective form in the beginning chapters of the book, so why it bears repeating is unknown.
- chapter 13 talks about the fear of change, a valid deterrent in upgrading. This is a good post, but would be better suited as the book’s introduction.
- a bona fide slap in the face, chapter 14 is almost a whopping 7 years old. While the author’s disclaimer mentions that the content is still relevant, I can assure you it isn’t, in any way. It talks of severely outdated framework versions that have lost all relevance today (the versions of CakePHP and CodeIgniter the book refers to are obsolete, ZF1, as bad as it was, was replaced by the anti-pattern plagued ZF2, and Symfony has changed its architecture completely since then).
In the outro, Chris says “I know there is a lot of stuff in this guide for you to consider.” but … there really isn’t. Books as outdated as this should be rewritten completely, their old content reworked to better fit into today’s context, and new editions should be published. That’s what new editions are for, after all.
Due to the limited amount of new knowledge absorbed by reading this short book, its low page count considering the price – especially considering you’re paying for two and a half chapters instead of 15 in this book, as it only properly starts in chapter 7 and ends in chapter 9 with the beginning of the blog copies – the occasional typos indicating the lack of an expert English editor, and its outdatedness, I give it a 1/5 and cannot recommend you purchase it.
I consider Modernizing Legacy Applications in PHP a much better reference to building testable PHP applications, because it takes a hands-on approach and covers testing alongside all other fixes and best practices. It’s more expensive, but well worth it.
The Grumpy Programmer’s PHPUnit Cookbook
Disappointed, I moved on to the second part of the bundle.
After an excellent foreword by Justin Searls, the first 22 pages of this book are a breath of fresh air. Already in this short segment one has learned more than in the entire first book – various options for running different types of tests and producing different output, fistfuls of good advice, and generally things that PHPUnit’s endless and intimidating documentation doesn’t make easy on newcomers.
While I would have preferred the code samples to be more real-world rather than foos and bars, the mocks and stubs are well explained, their sub-types defined (spies and dummies!), and example use cases presented. In the Test Doubles chapter alone I went from an attitude of “Why would I use a mock when I can just use the real class” to “Ok, I’m not going to use real classes any more”. The chapter on Data Providers was as brief as one could make it, yet it explained some things I never knew in under 10 minutes – had I read it before writing the post I mentioned in the introductory paragraph of this review, I would have avoided Matthew’s scorn :)
The book is far from perfect and has its downsides. Once again, there are slightly outdated installation instructions. PEAR is again mentioned with Composer’s somewhat outdated approach in the forefront. This entire part can be reworked into a single paragraph where PHPUnit is in a
composer.json’s “require-dev” block, though given the audience it’s questionable whether or not we actually need any installation instructions at all – the book is aimed at people who are already interested in PHPUnit and thereby are probably already using it. Removing installation instructions altogether would increase the longevity of the book while focusing on the target content sooner.
Likewise, the book needs updating to the most recent PHPUnit version where, for example, there is no longer a “getObjectForTrait” but this.
As in the previous book, links need updating and there are also some spelling (“Testing API’s”) and formatting errors in the book, indicating again the lack of a technical editor, but nothing major:
All in all, the downsides I mention are nitpicking – the second book is an excellent user guide to PHPUnit, and I’m actually excited to go forth and test, test, test. 3.5/5 – would have been 4.5/5 if the above issues weren’t present.
As a sum of its parts, the bundle disappoints. The first book was a complete miss, but I do like and intend to continue using the second one as a future reference, particularly if updated. It’s just sad to see, once again, the lack of quality in Leanpub publications. People who are not formally trained in passing on knowledge often refuse to admit they need professional help and ask friends, colleagues and family for reviews and opinions – this is a horrible idea. What’s needed is an unbiased professional who can give it to you straight, correct your errors in some cases and point out missed marks in other cases. Outdated instructions are one thing, and the sole responsibility of the author, but technical errors, dead links and formatting issues are all easily fixable in the modern publishing world, and there are no excuses for them – in blog posts or books.
For example, there is an easy fix for dead links. Direct links in your book to shortened forms, and change the endpoints of shortened links when updating is required. No need to republish your book that way, then. For example – a link that says “latest documentation” but leads to the docs of PHPUnit 3.7 is far from latest. However, if you make it point to something like
http://grm.py/phpunit_assertdoc_latest, all you need to do is alter the ultimate destination on the link and you’re all set, indefinitely. You can even set a reminder for yourself to check the links every 6 months – it shouldn’t take more than an hour when they’re all in one place, easily updateable.
All in all, I’d recommend getting the PHPUnit Cookbook if you find it on a discount – but until it gets some love from the author and is refreshed, paying full price for it just isn’t worth it. Go read Modernizing Legacy Applications in PHP instead – you’ll learn more on real, memorable examples.
Bruno is a blockchain developer and technical educator at the Web3 Foundation, the foundation that's building the next generation of the free people's internet. He's also a DX person at Diffbot. He runs two newsletters you should subscribe to if you're interested in Web3.0: Dot Leap covers ecosystem and tech development of Web3, and NFT Review covers the evolution of the non-fungible token (digital collectibles) ecosystem inside this emerging new web. His current passion project is RMRK.app.