Testing is a passion of mine and it’s something I expect to write about a lot more in the future. What I feel is discussed less often though is “Why are we writing tests?”
When many people talk about writing tests they talk about writing Unit Tests, classes and methods broken down into small, isolated areas of code which can be examined with tests to guarantee code quality. Let’s look at an example:
public string ReadText(string filename) { if(File.Exists(filename)) { return File.ReadAllText(filename); } else { return null; } }
This code reads the text in a file and returns it, if the file doesn’t exist it returns null.
The thing is, this is trivial code. Writing Unit Tests for something like this is overkill surely? That thirty minutes or so could be invested in the next feature, a bug fix or meeting the tight deadline.
Let’s suppose another developer comes along in a few years time, they see this method and know something their predecessor didn’t. .NET has a FileNotFoundException exception! Deciding to be a conscientious coder they update the method to throw an appropriate exception if the file isn’t found.
public string ReadText(string filename) { if(File.Exists(filename)) { return File.ReadAllText(filename); } else { throw new FileNotFoundException(string.Format("The file '{0}' was not found", filename)); } }
Unfortunately our conscientious developer missed something. One of the myriad of methods which calls our methods is GetOrCreateFileWithContents
public string GetOrCreateFileWithContents(string filename, string defaultContents) { var currentContents = ReadText(filename); if(currentContents == null) { currentContents = CreateFile(filename, defaultContents); } return currentContents; }
Because of our change this method now fails, ReadText throws an exception and the new file is never created in it’s place. This may be an oversimplified example with an overzealous and (dare I say it careless) tidy up but it illustrates the risks we take every day when refactoring and improving code.
This is the true value of Unit Tests, not in finding bugs but in defining the behaviour of the method. If our original developer had invested that extra thirty minutes our Boy Scout would have had some warning when then tried to update the method, they’d have seen that they’d changed the behaviour of the class in an unacceptable way and wouldn’t have made their changes.
The moral of the story? Unit Tests may seem like overkill while you’re writing them. But spare a thought for the poor soul who’s trying to read your methods in a few years time… Leave them a map, a series of executable tests which guarantee that your required behaviour remains unchanged. Your thirty minutes could save them hours, prevent bugs being introduced and help keep your application stable.
One thought on “Why write Unit Tests?”