We all will agree that having good tests to exercise and validate a developer’s code is a good thing. Unfortunately, so often, writing unit tests is the last thing developers have time for, if they get the opportunity to write them at all.
An example that developers can find themselves in: a development cycle or iteration is drawing near to delivery and the time and effort that was planned for testing to validate the code is spent still trying to “get the code to work” or making fixes to bugs that a few hasty tests drew out. This is not an ideal situation.
Test-driven Development (TDD) turns this situation on its head. Write the tests first then develop the solution. Write tests that demand a solution(s) that meets the business’ needs. Develop the code to pass the tests and you have found the solution. While on the surface this may seem straight forward and simple, but outside the theory, where the rubber meets the road… not so much. There are many situations that make this approach difficult; a few things come to mind like user interfaces or data conditional logic that is not available during unit test runs, not to mention the fact that developers despise writing unit tests. While TDD may not be beneficial in every scenario, we shouldn’t throw the good out with the bad.
What are some benefits that writing the tests first and then coding to the tests provide? Why would I ‘waste’ my valuable development time writing tests upfront?
Several benefits that I have reaped from having tests drive my coding:
Articulating the business needs in code.
Just as development patterns use interfaces and abstract classes to define and structure coding contracts, writing tests before writing functional code helps define a developer’s contract of what that method/class/factory/etc. is intended to produce. These tests help flesh out the design. The sooner that ‘contract’ is in the code, the less likely the developer’s time is wasted redoing and re-redoing code due to the losing sight of the goal.
Less time spent arriving at a solution.
More is less. The sooner a developer knows a piece of code is working incorrectly than the faster and easier it is to fix. The sooner a developer knows that the new code written has just broken existing code the quicker a resolutions can be found. With writing tests first the developer knows when the solutions has passed muster and will continue until it has reached that point. The tests serve as a better reminder of unfinished code than some TODO or FIXME.
Better code quality.
As a general rule: the more weight toward quality than quantity, tests exercising a piece of code, than the fewer defects it will have. While writing the same tests before or after the implementation may not affect the quality of the test, it guarantees that the tests get written.
These are just a few examples of how writing tests up front can benefit the development process. These are not meant to be a comprehensive list, but these have been the key benefits that I have seen from writing tests to drive my development of the solution.
So you say, “That’s great Josh, but we can’t do that because of XYZ.” While TDD can be difficult in different applications or layers of code (think UI), there are many tools that can drastically help. Selenium can help create UI testing. Mockito can help mock in data dependences. JUnit and TestNG are also great unit test frameworks. Using continuous integration systems, like Hudson, to run and report on the status of an application’s tests will provide updates to the progress of development. All of these tools and frameworks add power and easy of use to testing.
There are many implementations of Test-driven Development. If you haven’t read Kent Beck’s book Test Driven Development: By Example or Ken Pugh’s Lean-Agile Acceptance Test-Driven Development: Better Software Through Collaboration, I would strongly encourage you to do so. These two books (especially Beck’s book) have been very helpful to me and will provide more breath and depth to having tests drive development.
Remember that testing code is still only worth the effort you put into it. Sloppy, limited, and incorrect tests will produce less than desirable results. This goes for whether or not the tests are written before or after development.
In summary, I don’t have a silver bullet to get every project done on time, under budget, and be a complete joy to work on, but I do believe that developing tests first and being proactive in the health of the code that you are developing will bring better quality, more available development time, and more satisfaction due to fixing less defects. I hope this post has been beneficial and will prick your interest enough to do some digging into Test-driven Development.
— Josh McKinzie, firstname.lastname@example.org