TDD is just about testing
TDD slows down development
TDD means creating lots of interfaces
TDD guarantees you to catch all the potential errors in a system
TDD guarantees you to design your system well
Test Driven Development defined
According to the wikipedia, Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards. Kent Beck, who is credited with having developed or ‘rediscovered’ the technique, stated in 2003 that TDD encourages simple designs and inspires confidence.
That’s right, you first write a failing test and then write just enough code to pass the failing test. Then you add to the test case, and write more code, etc, until you have satisfied all your requirements. Then refactor test code and application code.
A more appropriate name for this development method might be “Test First Development” because it is a development technique where the developer writes the tests first. Or, you could call it “Test Driven Design” because the tests drive the design of the application. What I am trying to say, is that TDD is not just about testing.
Build the right application
What do we hope to achieve with Test Driven Development? One goal is that we build the right application. TDD forces us developers and business analysts to think about the requirements and focus more on what the application “should do” rather than getting lost in creating an overly (or underly) complex system design that isn’t really what we want at the end of the day.
Test Driven Development also helps developers, business analysts, and customers work well together as the application evolves. Acceptance Testing provides a way to identify the requirements and coordinate development projects so that the customer is guaranteed to get exactly what they want. It keeps developers from writing code when requirements are poorly defined and creates a good contract between the developer and the customer.
Build the application right
Not only do we want to build the right application, but we also want to build the application right. Writing tests first forces us developers to think of everything that can possibly go wrong, so we produce cleaner code with less errors. It also forces us to think of everything that should possibly go right. As we brainstorm for test cases, we begin developing code that performs exactly as it should, not just as we think it should.
Of course, TDD has to be done right, in order to leave us with a good application design. The goals of an application that works and is designed well cannot be achieved if we leave out the refactoring step. Refactoring allows us to constantly improve the application design and let it evolve naturally, although it is not a bad idea to think of the overall design and “big picture” along the way. As the application grows and evolves, and with the constant addition of new features, it is important to have unit tests to ensure that the introduction of new features does not introduce new bugs. That is another bonus of TDD.
The best thing about TDD is that it fits perfectly for projects on the Agile Development side. Agile Development is a big deal in software development today. The method is so heavily used due to the constant evolution of application requirements among other things. What is agile development? Here is the definition from the wikipedia: Agile software development is a group of software development methodologies based on iterative and incremental development, where requirements and solutions evolve through collaboration between self-organizing, cross-functional teams. It promotes adaptive planning, evolutionary development and delivery, a time-boxed iterative approach, and encourages rapid and flexible response to change. It is a conceptual framework that promotes foreseen interactions throughout the development cycle.
Agile Software Development became so popular that several methodologies emerged to shape the development process. One is Extreme Programming, which is a discipline of software development that follows a specific structure, defined by Kent Beck. The aim is to develop software quickly in small teams where the requirements are rapidly changing. Here is a good introduction to Extreme Programming.
Big Design Upfront (BDUF)
The opponents of Agile Development and Extreme Programming might be of course the proponents of Big Design Upfront (BDUF). This is a different approach to software development. As stated in the wiki, Big Design Up Front is a software development approach in which the program’s design is to be completed and perfected before that program’s implementation is started. It is often associated with the waterfall model of software development. As you can imagine, the principles of Test Driven Development are somewhat opposed to the principles of BDUF. Test Driven Development encourages a sort of “design as you go” approach, whereas Big Design Upfront encourages you to design the whole system before you begin building it.
Which is the right approach to development? Agile Development, Extreme Programming, Big Design Upfront…. those are just a few of the well known development approaches. There are many others. So then, how do we know exactly how to develop our systems today? I always like to give objective advice because I am not trying to sell anything here, anyway. I would say that the answer is always somewhere in the middle. The risk of Agile Development is that it can sometimes lead to a very messy system and constant refactoring which can sometimes introduce new problems if we aren’t careful. Consider how that compares to the risk of Big Design Upfront, which is that we might design the system too early, when we are not entirely certain of the requirements. This might mean implementing functionality that we do not need or creating a design that is too complex for the actual requirements (or not complex enough). The bottom line is, TDD is an agile methodology that in theory creates a good application design if we do it right. Of course, as with everything, don’t forget to add a little bit of common sense and always think about the big picture and the direction you are moving towards.
Basic Testing (Java Example)
Mocking with interfaces (Java Example)
Mocking with subclasses (Java Example)
Rules for creating a testable design
- Manage dependencies (isolate & inject) (TDD in action)
- Create simple constructors (javaworld)
- Choose composition over inheritance (TDD in action)
- Avoid static and the Singleton (TDD in action)
Frameworks for easier mocking