Productivity gain when PHPUnit testing decoupled code
Over the weekend I started writing some code just to try out a few ideas. Over the last four years I have been writing a lot of code but best of it was related to symfony. So this was a nice situation to start something from scratch.
Of course I experienced a lot during the past and also did I learn a lot from participating – actively and passively – in the symfony community. The most important fact I learned is that the key principle of programming that decides about if your code gets manageable is: Separation of Concerns.
And with my small experiment I also learned that following it reduces the time you spend writing unit tests!Of course it sounds reasonable that it will be easier to write unit tests for decoupled code than for coupled ones and I would always have nodded right away. But it is only when you experience such a situation that you realise how much productivity coupled code costs you!
For my experiment I followed Separation of Concerns by using Dependency Injection instead of hard wiring the dependencies. So instead of calling the new operator in my classes methods I create those needed instances outside of these classes and pass them as attributes to constructors or mutators or as arguments to methods that act on them.
Instantly my PHPUnit test cases became simple as A B C.
For symfony plugin code I always needed to bootstrap a lot to make the dependencies available.
- Often you needed to bootstrap symfony to get sfContext available.
- Often you needed to boostrap symfony to make the configuration available needed for some of the classes depending on.
- Often you even needed a database connection fired up as doctrine required that for almost everything.
All because of hard wired dependencies inside symfony and doctrine.
Knowing this is simple and understanding this just as well. But after experiencing it I conclude that the productivity gain for writing unit tests is about two thirds! I only needed a third of the time writing PHPUnit code that I needed in coupled sources.
Even refactoring the unit tests when changing the architecture now couldn’t be simpler.
That’s another good reason to look forward to Symfony2 and Doctrine 2.