As someone who’s seen the benefits of the approach, I’m a huge believer in test driven development. It adds a level of quality and maturity to the field of software development, yet it’s still not a widespread practice across development projects. When it comes to a choice between the features, time and quality, it’s always the quality that suffers. We don’t want to add extra time for testing and we don’t want to compromise on the feature set of the delivery. If you haven’t set out to do test driven development at the start of the phase, then it’s difficult to fit in.
We’ve all heard excuses for not taking the test driven approach, but nowhere compiles them better than “Pragmatic Unit Testing in Java With JUnit“, from the Pragmatic Bookshelf. I read the book a few years ago, and afterward I thought there was no way that any responsible developer could read the book without truly believing that unit tests were one of the most important aspects of the development activity.
The most worrying excuse I’ve heard is that it’s too difficult to test my code. This can be for one of two reasons. One is that your code is mainly UI related, and automating the UI tests is too difficult. I’ll concede that UI automation is a tricky area (but not impossible, as we’ll see in a later article), but every effort should be made to automate it if possible: think about regression tests. If you have a fully automated test suite, including the UI behaviour, you can make a change to your code, and have full confidence that you haven’t broken anything if you have tests to re-run.
The second reason that your code is too difficult to test is that you’ve messed up your design. Maybe your logic and UI code are too tightly coupled, and without that automated UI layer existing, the dependency between the logic and the UI will cause a problem. This is where test driven development helps to ensure a clean design, following best practices. Using JUnit is simple, so if I can just point my test at a clean logic layer, I can test all logic that the UI will ever touch. What’s that? You’re missing your data model? Well then just use mock objects – there are many frameworks for that!
For those who haven’t read the book yet, I’ll give a quick summary of the excuses for not testing as outlined in the introduction chapter:
- I don’t have time to unit test.
- Really? But you have to time to fix your mistakes later? The simple fact is that nobody, not even you, can write bug free code. Unit tests greatly speed up the time it takes to identify a bug because they narrow the suspect code down to a very specific unit. Other types of testing, such as Quality Assurance or User Acceptance Testing, identify problems at a much higher level, forcing the developer to spend extra time plodding through the various units looking for the root cause. Unit tests can also serve as verification that the bug is corrected without having to go through the hassle of creating a new application build and deploying it for further testing. Simply put, unit tests speed up overall development. It might take slightly longer to create each new feature, but the development time for the entire application, from inception to delivery, is considerable shorter.
- The client pays me to develop code, not write unit test.
- News Flash – Unit tests are code. They are as integral to the application as any other piece of code you are writing, and should be included in the original estimate and statement of work. It might also help to mention to the client that unit tests lower both development cost (see previous excuse) as well as maintenance cost. If you are not writing unit tests, then you are doing your client an injustice by forcing them to incur extra expense.
- I am supporting a legacy application without unit tests.
- That still doesn’t preclude you from writing your own. Granted, you are not going to be able to go in and write tests to bring the entire code base up to an acceptable level of coverage. You most likely don’t have the time or resources to do that. But as support issues are raised, write the unit tests for any code that you modify. When I am working on a support task, one of the very first things I do is write a unit test to recreate the bug. When the unit test starts passing, I know that I have fixed the problem. Now, not only have I resolved a bug, but I have added some unit test coverage to the code base. Over time, this coverage will become more and more robust, and actually reduce future maintenance costs by preventing the introduction of regression bugs.
- QA and User Acceptance Testing is far more effective in finding bugs.
- No arguments there. But Unit Testing is far more effective at preventing bugs. Just because my smoke alarm is better at detecting potential fires doesn’t mean that it is safe to leave the stove on all the time. QA and UAT are smoke alarms – they alert you to potential existing trouble. Unit testing is turning off the stove when you are done – it helps you prevent trouble. Unit testing, QA, and UAT are all important parts of the testing process, and they each play very different roles. Trying to replace one with another doesn’t work. I wouldn’t release a project that was well unit tested without QA, and I wouldn’t release a project that was thoroughly QA’ed without unit testing.
- I don’t know how to unit test, or I don’t know how to write good unit tests.
- Well, this is probably the most valid excuse that is out there. The sad truth is that a great many number of developers and engineers do not know how to unit test. I didn’t when I started. And nothing discourages a developer more than struggling to write bad unit tests. Luckily there are resources out there. There are so many books, webinars, conference presentations, blogs, etc on writing good unit tests that the inability to write them simply isn’t going to cut it as an excuse any more. When someone offers me this excuse, I don’t look at it as a roadblock, but rather as a teachable moment. It usually only takes a time or two of seeing how well written unit tests can help one develop code to turn them from the dark side…
Are there other excuses out there? Absolutely. But they are just that – excuses. I have yet to encounter a valid reason to skip unit testing. If you think you have one, post it here. I look forward to the challenge of changing your mind! 🙂