John
John

Reputation: 443

How does TDD drives the design?

I understand that TDD has many advantages (some of them are below). How ever I am not sure how it drives the design?

  1. Serves as documentation
  2. writing tests before actual code helps maximum test coverage
  3. Help determine input value boundaries

Usually when we start implement new piece of functionality, we will have rough idea of the design. And we start with TDD implementation of a class, which is used by other classes as per design. This understanding of mine seems to be in conflict with statement "TDD drives the design"

Please help me understand this by an example.

Upvotes: 2

Views: 710

Answers (5)

hspandher
hspandher

Reputation: 16753

Most people think that Test-Driven Development is tool to write code with lesser number of bugs. But ,in reality, that is the by-product of TDD. TDD is more of a tool for code designing.

Overall, TDD helps in quality code development in following ways:-

  1. It makes you think about your code design and requirements at every stage, thereby ensuring that you are actually implementing what is required.

  2. You are forced to write testable code, thereby ensuring that your code has loose coupling and high cohesion.

  3. If your code is getting difficult to test, mostly is signifies that there is some issue with your design(Your code is too coupled or not isolated enough)

With that said, I tend to disagree with people that think if you follow TDD blindly you'd always end up with good code design(because that depends more on you and your knowledge of Sofware Design), but I believe there is a good chance you would.

Upvotes: 3

Peter Wiles
Peter Wiles

Reputation: 406

Great observation by Mark Seemann. The principle that pushes me to value TDD is fast feedback (and so fast learning). You can't substitute good design techniques for just doing TDD - learn good design principles and use TDD to provide fast feedback on your work.

I find that when using TDD most deeper thinking about my design happens during the refactor step and the tests then provide a space for that step and a safety net for change, but it doesn't automatically create good design.

TDD allows me to hack some working code and use the learning I get while doing that to iterate towards a better design. Of course this can be done without TDD too, but the test helps by providing that safety net.

Upvotes: 0

Mark Seemann
Mark Seemann

Reputation: 233237

TDD doesn't drive design, but it's an excellent feedback mechanism, which enables you to get rapid feedback on your design ideas.

It also has the beneficial side-effect that it leaves behind a nice regression test suite.

Upvotes: 2

eliasw
eliasw

Reputation: 720

TDD in general The goal of Test-driven Development (TDD) is to create software components that are precisely conforming to a set of functional specifications. The task of the tests is to validate conformity and to identify disparities from these specifications.

Design Guidance By writing tests first, you're forced to make up your mind what your software component should do. Thinking about meaningful test cases first will guide your design, as you're forced to find answers to a set of questions: How should process inputs? To which components does it interface? What are the outputs I'm expecting? ...

TDD does not replace SW design. It sharpens your design! In essence, TDD will help you to sharpen your design - but one thing is crucial: You need to find reasonable tests. And trying to replace functional specifications - call it a requirements documents - with tests only, is rather dangerous. Why? Unit tests as used by TDD can only guarantee that your components exhibit the expected behavior for the given test data, but not for any data! As Dijkstra said in the 1960s: "Testing shows the presence, not the absence of bugs".

> Usually when we start implement new piece of functionality, we will have rough idea of the design.

That's the core thing of your question. If you just have a rough idea of the design, you better should spend more time at the drawing board, asking your self questions like: What are the individual tasks my software should carry out? How can I split the general task into subtasks? How can I map these subtasks to components? Which data needs to be passed among them?

At that time, you might consider doing TDD. But without thinking about a design or software architecture first, you'll end up with a "spaghetti system" that is hard to understand and hard to maintain later on.

Upvotes: 1

BartoszKP
BartoszKP

Reputation: 35901

The most basic idea behind this, is that when you want to test something, you want to keep the tests simple and focused. This in turn forces you to start with the smallest bits of your problem, driving towards the Single responsibility principle.

Another thing, for larger problems, is when you are forced (because you want your tests to be focused) to use mocks and stubs. This drives your design towards using the Dependency inversion principle, which in turn makes your code loosely coupled.

Upvotes: 1

Related Questions