The Grumpy Programmer's Guide To Building Testable PHP Applications (2015)
1. Testing Is Good, Testable Applications Are Better
There is no denying that the PHP world has finally caught up with other programming communities in terms of its attitude towards testing. As a result, you can find a lot of really good resources either online or in book form from your favourite retailer.
Most of this information focuses on the actual writing of tests and strategies for the type of tests you need to write. What I found was missing from most of these resources was how to write applications that you could actually test. Sounds like something obvious, at least to me.
There is an open secret out there: some applications can never be tested with automated testing tools. They’re built in such a manner that you couldn’t wrap anything beyond tests that examine the HTML output from it. That’s really a shame, because these sort of things don’t happen on purpose. Like technical debt in your code, it builds up over time and at some point you end up with an application that might as well be a black box: you put inputs into it and you get output back, and have no easy way to determine how to fix things if it sends you back something you don’t expect.
But make no mistake: building a non-trivial testable application is something that actually takes experience. A lot of experience. You will mess up. You will need to refactor things at a later point, and will often find that refactoring to be painful when contrasted with the seemingly-simple feature request that you are trying to implement.
I am a big believer in the power of automated testing to give you an application that is maintainable, extendible and performant. I don’t always get to work on applications that have made a commitment to be testable. It really is a different way of looking at the entire process of testing. It’s one thing to know how to write an assertion statement, or understand how to use mock objects to isolate components of a module that you are trying to test. It’s another to have to create an application that lets you test it from end to end.
I am hoping to pass on my thoughts on building applications that you can easily test, and show you some of the techniques that I use to try and make the job easier. In this guide you will learn about creating the proper environment for your application, a programming concept known as Dependency Injection, and some best practices for testing the output of your application from the command line.
I really think that an optimal architecture for a web application is to build small modules of code that you then integrate together to solve larger problems. There is no other magic bullet to build a complicated system. I have run across an old saying (that I have been unable to find an attribution for) that says “simple systems can display complex behaviour but complex systems can only display simple behaviour”.
Keep your modules, components, libraries, whatever you decide to call them small, readable, and easy to verify that they work as desired in isolation or when integrated together. That way you will have an application that is very easy to write tests for and provide you with some protection against regression errors and other unexpected bumps in the road.
The goal is always the same: create a workflow that shortens the time it takes for code to make it from your text editor of choice all the way into production with the fewest bugs possible.