Grumpy Programmer’s Testing Bundle: Review

By Bruno Skvorc

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 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
	-> expects()
	-> method( 'getUri' )
	-> with( '/dashboard' );

… while technically sound, is not dissected. Finding out what the expects, method and 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, 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, 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.


Have you read Real-World Solutions for Developing High-Quality PHP Frameworks and Applications by Sebastian Bergmann et al (author of PHPUnit)? There is a ton of good advice in it.

Unfortunately second edition of the book is only available in German at the moment.


I did not, but I've put it on my to-read list, thanks.
German is fine : )


Haven't read your review yet, but just wanted to point out that I really like SitePoint is reviewing PHP books.


Thanks! I try to be as objective as possible and make myself not pull punches - generally trying to write reviews like those I'd find useful before thinking about the purchase of a book.


Based on what you had to say about the first book I am surprised that you rated it one out of 5. The last time I reviewed a book that was that outdated I gave it zero out of 5.


You can find the second edition here.


The first half is "ok" for someone who isn't introduced to the basic concepts I mention and can therefore be useful. A book would have to be actually harmful for me to give it a zero, which this is not.


Thanks for the good review Bruno!



Sounds reasonable.


Author here. Can't find much to disagree with in Bruno's review. The book needs an update as things have changed. It is on my list of things to do in the spring.


I saw your avatar on the post before clicking into it and thought "I bet that's the author".

Was not disappointed.


Looking forward to it, thanks for chiming in!


I really like the idea of review. Keep it up the good work @swader . Can't wait for new reviews smile


Thanks, much appreciated!


re: "Go read Modernizing Legacy Applications in PHP instead – you’ll learn more on real, memorable examples."

Why not just start here and not waste so much bandwidth (and my time) telling us what NOT to do?

In any case, thanks. This was a good reminder either way.


Um. Well, so you know in the future - I always put a conclusion at the bottom of my reviews, along with a score, so if you stumble upon any future ones, keep that in mind.


Um. Because everyone always wades through a pile of shit to get to a one line of real / useful value? It was obvious pretty early what you weren't interest in. We got the point.

I have to tell you, I think you're losing more people than you're enlightening. Is that the goal?


You're thinking in terms of value only to you.

Why "wade" further, then? The value of a review is objectively explaining what's wrong so the author can focus on it. If you're not interested in the details, skip to the end.


Yes, please don't speak for me. I don't know you and you don't know me, so please don't say "We", as it isn't the case (and unless you are voted as a spokesperson by a group of people or are the leader of anything, it is actually always the case).



People time is limited. It's gone when it's gone and there's no way to get more. I think if you showed some empathy for such fact the approach here would be much different.

Or perhaps it's because Sitepoint pays by the word? wink



It looks like you missed reading this in the first paragraph

It was my hope that those books will prevent me from using the shoddy practices .....
..... how much this helped me, if at all.

The "was" and "if at all" speak volumes to me as to what to expect.


Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in PHP, once a week, for free.