This is an extract from the Unit Testing Succinctly eBook, by Marc Clifton, kindly provided by Syncfusion.
The usual mantra we hear regarding any software methodology is that it improves usability and quality, reduces development and testing time, and brings the product to market faster and with fewer bugs. These are lofty goals, but I have yet to see a methodology deliver the Grail of software development.
Ultimately, the primary reason to write unit tests is to prove correctness, and this happens only if you write unit tests well. Unit tests by themselves will not directly improve the usability or quality of your product. You can still make a mess of the application whether it’s proven correct or not—and it certainly is not guaranteed to reduce development and testing time (more on this later) or bring your product to market sooner.
So, let’s be clear and real from the get-go: unit testing can be used to verify correctness, and any side effect that occurs with regard to your development process must be balanced with the effort of writing and maintaining useful unit tests.
Well-written unit tests will give you a measurable degree of confidence that the myriad of methods that comprise your application will behave correctly. The simplest way to objectively make this measurement is a coverage test: What percentage of the methods in your application have unit tests written against them? While this question does not directly address whether a method should be considered a unit (discussed later), or whether the tests are meaningful, it is nonetheless a measurement that you can take at any time and can be used as a benchmark for the correctness of your application.
Unit testing is an iterative process—there will always be bugs that are missed with unit testing. However, the number of bugs reported over time and the number of unresolved versus resolved issues provides meaningful information regarding your application’s health. While it is impossible to say, “With unit testing, the number of bugs has been reduced by 50 percent,” it is possible to measure how many bugs your application has because of incomplete unit test coverage. As you write unit tests to verify the issue and the fix, you can also measure how many unit tests you have written against reported bugs as compared to the total number of unit tests.
All of these benchmarks bring a degree of objectivity to your development process. Therefore, one of the benefits of unit testing is that it provides everyone, from developers to managers, with objective information that can be fed back into the development process to improve that process.
Repetition, Repetition, Repetition
Another benefit is repeatability, otherwise known as regression testing. As an application matures, we want to ensure that existing, working code is not broken. By writing unit tests against methods as they are written and adding unit tests for bugs as they are reported, all of these can be retested automatically when new code is added or existing code is changed. Unit tests become a significant time-reduction tool when it comes to testing whether an application still behaves correctly after a minor or significant code change. While unit testing does not replace usability testing, performance testing, load testing, and so forth, it definitely helps to eliminate the time wasted on the common question: “This worked before; why doesn’t it now?”
It’s easy to test that a method is doing the right thing when all the processes in the method execute linearly. However, once you add an
if statement or a
switch statement, you are creating cyclomatic complexity, which is a fancy way of saying that your code now has multiple paths of execution. The most useful unit tests are those that test every single code branch that occurs in your method. Writing these kinds of unit tests can be painstaking but are well worth the effort, as they guarantee that at least every code branch has been executed, which is not something that may occur during acceptance testing, usability testing, or other testing that the quality assurance department (if you have one) performs.
Throughout this series, we're going to take a look at a number of different strategies and tips for how to perform effective unit testing.