Envoyé par
Robert Cecil Martin
The idea that the high level design and architecture of a system emerge from TDD is, frankly, absurd. Before you begin to code any software project, you need to have some architectural vision in place. TDD will not, and can not, provide this vision. That is not TDD's role.
However, this does not mean that designs do not emerge from TDD – they do; just not at the highest levels. The designs that emerge from TDD are one or two steps above the code; and they are intimately connected to the code, and to the red-green-refactor cycle.
It works like this: As some programmers begin to develop a new class or module, they start by writing simple tests that describe the most degenerate behaviors. These tests check the absurdities, such as what the system does when no input is provided. The production code that solves these tests is trivial, and gradually grows as more and more tests are added.
At some point, relatively early in the process, the programmers look at the production code and decide that the structure is a bit messy. So the programmers extract a few methods, rename a few others, and generally clean things up. This activity will have little or no effect on the tests. The tests are still testing all that code, regardless of the fact that the structure of that code is changing.
This process continues. As tests of ever greater complexity and constraint are added to the suite, the production code continues to grow in response. From time to time, relatively frequently, the programmers clean that production code up. They may extract new classes. They may even pull out new modules. And yet the tests remain unchanged. The tests still cover the production code; but they no longer have a similar structure.
And so, to bridge the different structure between the tests and the production code, an API emerges. This API serves to allow the two streams of code to evolve in very different directions, responding to the opposing forces that press upon tests and production code.
I said, above, that the tests remain unchanged during the process. This isn't actually true. The tests are also refactored by the programmers on a fairly frequent basis. But the direction of the refactoring is very different from the direction that the production code is refactored. The difference can be summarized by this simple statement:
As the tests get more specific, the production code gets more generic.
This is (to me) one of the most important revelations about TDD in the last 16 years. These two streams of code evolve in opposite directions. Programmers refactor tests to become more and more concrete and specific. They refactor the production code to become more and more abstract and general.
Partager