Last week, we had a discussion on my project about what we should test. For sure there is a boundary for test, but where does this boundary live? I'm an advocate for tests, mostly unit tests. I think by using unit tests we have documentation about our classes and also good and quick feedback on what we're doing. It is a good safety net.
Ok, but everyone knows that. What happens when takes too much time to create a test? It happens in legacy systems when classes have big methods, use a lot of static methods, no dependency injection, etc. But everyone knows those classes are working, because the system is working. It is legacy code, but it is also working code. Should we test those classes? In this discussion, one of the members of my team Fernando Freire, told me about a presentation (only in Portuguese) from Lucas Cavalcanti at Agile Brazil. This presentation is about Premature Optimization and it is about how and when clean code and good design practices can help us to deliver. In this presentation Lucas uses a pseudo-graph from a Martin Fowler post.
Well, the graph shows the delivery curve using good design and also no design. In the beginning, the team that uses no design "practices" can delivery faster than the other team that uses good design practices. But this changes after some time and the team with good practices delivers more. The problem is how long is this "some time". It is very difficult to estimate. It depends of the project, on the team and when we have to deliver.
After this discussion, I thought a lot about this graph. When is it safe keep moving with fewer tests and when do we have to use all the good practices to slow down the team. I'm pretty sure that the answer to my question above, about to testing a class that is hard to test, is that it depends. If you have a tight deadline and you're not changing this class, well, you don't need to test it. But if you know you'll have to change this class a lot, then I think it is worth spending some time to cover it with tests and to refactor it to make the class more simple and readable.
Actually, I had to to take a decision like this. I was pairing with Darius and we were changing the patient registration module to be able to add two new fields in the check-in flow. The code wasn't that good and we didn't have any unit tests testing it, after some discussion, we realized that refactor everything to able to test it won't be a good decision. It would take too much time and it won't bring much business value since we didn't have plans to change that screen in our short period of time. After 1 month, I still think that was a good decision and we saved a lot of time.
My conclusion after this discussion is: we cannot compromise our delivery because of good practices. The good practices were created to help us to deliver more, to create more value for the client. If good practices are slowing the team down, something is wrong. I know its easier said than done. Sometimes this boundary about what and when to test is hard to see. Actually, most of the time this it is VERY hard to see. But this is what Agile is about right? If we focus on delivering value, we'll learn where this boundary lives and learn how to improve the team velocity.