Monday 22 May 2017

Homework Excuses


The majority of developers will recognise the benefits of unit testing and most will make an effort to write some.
But often the determination to ensure high test coverage can be paper thin with excuses often being made for why in this instance we won't write tests or fix the ones we've broken.
On a large number of occasions the root of these excuses will highlight something more fundamentally wrong with a code base.
False Assurance
Sometimes a justification for not writing unit tests right now is that "I know this works".
Firstly, I'm sure all developers can recall a time when their certainty in something being true has turned out to be false, this would come under the same category as "I haven't changed anything" or "That can't happen".
Unit tests not only prove a class does its job but it also ensures that it is achieving this outcome in a way thats expected.
Secondly, and probably more importantly, the value of unit tests isn't really in proving that code works at the time of writing. As professional developers this should be a given, pull requests shouldn't be raised for non-functional code.
The real value of unit tests is proving code works at any and all points in the future. The longer you leave code uncovered by unit tests the wider the window that a bug or regression will be introduced unseen by the team and possibly making it into production.
A healthy if slightly distrustful attitude in this situation would be "you say this works, show me the tests".
This Is Hard To Test
Another common excuse is that this particular class is hard to test.
Sometime this can be true for a variety of reasons, but a healthy attitude to this situation is to assume that this must mean some refactoring is required, with code only being declared untestable when a clear rationale has been defined.
This should largely only be the case when the code that requires testing has a dependency on something we don't have the ability to change or that cannot easily be mocked.
Un-testability is something that can spread through a code base like a virus. An untestable class spreads the disease to every class it becomes a dependency too. The result of this is that the scale of required refactoring increasing rather than our code coverage.
So whenever someone declares a class untestable assume that this is our fault until proven otherwise.
Much More Than Testing
While the major benefit of unit testing will always be testing our code it does bring other benefits that shouldn't be dismissed.
I am a big believer that unit test make the best code documentation. On many occasions when wanting to understand more about how a class is supposed to be used I have looked through the unit tests, when these tests are well written I find a plethora of information about how a class is interacted with, what error conditions can occur and what output I should expect to get from it.
Unit testing is also a key part of building a continuous integration and deployment workflow.
Whenever we talk about CI we are not referring to a pipeline that continually delivers code of a questionable quality with a varying probability of working.
If we intend to automate the delivery of our software then we must create an environment where we can automate some degree of certainty that things are working.
This will never be full-proof, even the most highly tested code has been known to contain bugs, but I would back it over a fingers crossed approach.
Whenever code is deemed to be untestable we need to view this as a design decision because it comes with consequences.
This attitude needs to be pragmatic as nearly all code bases will have areas that genuinely aren't practical to unit test, but this should be a last resort with a clear rationale not an immediate decision made every day.

No comments:

Post a Comment