I’ve been working hard the last six months teaching my teammates about unit testing, code reviews, SOLID, SCRUM and anything else I think we can benefit from. I feel lucky – for the most part they are open minded and accept my ideas and try them without prejudice, working this way has enabled better code and work for both the team and myself.
Over the last months the team’s productivity has increased, the unit tests got a lot better and the code has improved dramatically. But not all is peachy – There is one methodology that I’m having only partial success in convincing my team that they should use – namely Test Driven Development (TDD).
While some of the team use TDD exclusively others still find it too hard and/or cumbersome to use on their daily tasks. I know they’ve tried, and failed using TDD for some of their tasks and now the only reason they keep on trying is because I insist they do it – without real benefits.
Why some fail while others succeed
I wanted to investigate why TDD worked great for some while completely missing the point for others – could it be that the tasks of the developers that used TDD were easier to test? perhaps the developers that didn’t manage to apply TDD worked more with complicated legacy code that was just harder to test?
After much investigation I came to the conclusion that to some extent the success or failure of TDD depends on how easy it is to write tests for that piece of code which is effected heavily from the amount of code existing before the change and how well it was previously tested. But that’s not the whole picture, when I look at the code written by the developers that found TDD to be “just too much work” I almost always see more than one assert which indicates that they might be trying to test too much –and if you write the tests before the code means that it’s a lot harder to do that when you’re actually planning on implementing a few features at once – not very TDD at all…
The TDD way
TDD is not about the tests – it’s about design:
By writing the test you actually create a form of specification (singular not plural!) and by making the test pass you satisfy the requirement. By this logic multiple asserts means (more often than not) that you’re implementing multiple requirements at the same time. Another issue with trying to write a test for multiple requirements is that the test tends to be much more complicated than a test that checks only one thing.
One final thought
Multiple asserts is not necessarily a bad things, there might be a valid reason to writing multiple asserts to test a single requirement.
I have a trick to check if a test maps to more than one requirement – ask the developer “what are you testing here”, if he uses “and” in the sentence i.e. “I make sure that the username is valid and an email is send” he might be testing too many things.