James Kovacs shares a great insight on software testing and the software testing process. His epiphany about test driven development makes it obvious to all of us why this technique is so powerful.
Test driven development is an approach to software development where you write the tests first, and the code second. This sounds ludicrous at first, but it really does work. Here’s James’ epiphany on the subject (emphasis added).
I didn’t understand why TDD practitioner were so zealous about writing the tests first. Why did it matter? I thought it was to ensure that some project manager doesn’t try to shave some time off the project by cutting the unit tests. Then I started doing some reading about TDD, poking around, asking questions, and trying it out myself. I discovered the real reason for writing tests first is that TDD isn’t about testing code, it’s about designing code.
Works Great With Structured Requirements
Not only is this a great way to approach design, but it is a great way to coordinate software development with structured requirements. A well-written requirement describes a need without specifying design. This description then works like a black-box contract. The implementer then must do something that meets the specification given. As James points out, TDD is very effective at creating black-box tests.
This makes sense, when you consider the outside-in approach that comes from starting with requirements. This outside in approach leads to API decisions (for a program or module or method). The API has to support all of the required possible inputs and outputs. Once an API is written, tests can be written.
Best Applied As Part Of Continuous Integration For Larger Teams
All of the tests will fail (because the code hasn’t been written). Then the implementer will write code until the tests pass. Using a continuous integration approach is a very effective way for entire teams to do this simultaneously on larger projects.
We can also validate the design for completeness prior to creating the implementation. We can compare the generated APIs (and their rationalizations) with the software specification (or application requirements, or FRS… see alphabet soup article). This allows us to address some refactoring needs before the code has been implemented – saving time and money.
Use TDD as an outside-in approach that assures that the delivered software will meet the objectives of the requirements specification. It also saves time and money by supporting validation in advance of implementation.