Doing code kata led me to reading up on Test Driven Development (TDD).
In WordPress world, writing tests is rare. WordPress itself has an extensive test suite. But most themes and plugins don’t have tests. Test Driven Development requires discipline no matter what kind of code you do. When most of one’s work is with WordPress, you know that doing TDD is going be paddling upstream.
Most of the classic books on TDD are written for languages like Java, C++ and Smalltalk. When the classics were written, PHP was just a web scripting language. There was no object oriented support and testing was still a long way off. So, as I’ve been reading, I’ve been reading a lot of C++ and Java. It’s almost like learning 2 languages on the side.
To help solidify the concepts, I went through part 1 of Kent Beck’s Test Driven Development By Example (2003). Beck builds a currency exchange calculator app, step-by-step using TDD – in Java. So, following along with his notes, I rebuilt it step-by-step – in PHP.
Between the two languages, there are two significant differences for purposes of the exercise:
- Java is a strong-typed language. PHP is weak-typed language. (See Strong and weak typing.
- Java is a compiled language. PHP is an interpreted language. (On Interpreted language.
So, while the logic driving the app’s function is the same, the implementation between the two is different. It helps that as of PHP 7 you can declare types for almost anything. (Previously you couldn’t type-hint primitive types. See Classes of data types.) And now with PHP 7.1 we can declare a null or void return type. At one point in the exercise, it would have been nice to be able to declare a generic
Object type, which is not supported yet in PHP. The work-arounds are either to pass an Interface if you can find one that covers all the possible objects you might get, or to leave it as a weak-typed parameter and check what comes in with
is_object(), throwing an exception if it’s not. (I found one suggestion to create an empty
Object Interface and then have all your classes implement it. But that’s just plain ugly, not to mention it won’t work if you’re using any kind of framework that doesn’t implement your custom
Object interface on everything!)
The second difference creates a different workflow as you write and debug. With Java, the compiler will tell you all the compile errors and you can deal with them all at once. With PHP the whole thing stops running on the first fatal error, and you have to deal with that one before the next is exposed.
I’ve posted the resulting PHP code to Github. Tests are PHPUnit, and they all pass. It’s probably not useful for anything in the real world. The value was in doing Beck’s exercise. If you have the chance and inclination. I highly recommend it.