TDD is dead. Long live testing
From the translator. David Heinmeyer Hansson, this article raised the hot topic of the mandatory use of TDD and, even, the possible harm from writing tests before writing code. It was this article that served as the leitmotif of five meetings on the topic of whether TDD is alive , at which David, Kent Beck and Martin Fowler discuss the strengths and weaknesses of TDD, the scope of applicability and limitations. For those who have a poor understanding of spoken English, SergeyT publishes brief sammari in his G + .
The fundamentalism of the “tests ahead” approach is sex education limited to abstinence: an unrealistic and ineffective moralizing campaign full of self-hatred and shame.
At first everything was different. My first acquaintance with TDD was like a kind invitation to the better world of programming. Change consciousness in order to continue to practice testing where there was no testing at all before. I saw the serenity of a well-tested code base, and the bliss of feeling confident in making changes to the code.
The “tests ahead” approach was wonderful support wheels, it taught me how to think about testing at a deeper level, but quickly enough I abandoned it.
A few years later, the rhetoric of “tests ahead” became louder and meaner. More mean. And from time to time I was sucked into the funnel of fundamentalism, I felt bad that I did not follow the true scripture. At such moments, I tried to practice “tests ahead” for several weeks, only to quit again when my projects got worse.
It was the effect of the pendulum: pride when I was able to stick to the letter of doctrine, and the collapse of despair when I was not. It's like starting to drink after a tie. To be silent and not appear in society. In public, at best, I said that I didn’t always write tests before writing code, and, at worst, I continued to support this approach as truly true. I'm sorry about that now.
Maybe it was necessary to use the “tests ahead” approach, as a ram to destroy the industry “sorry, we do not have automated, regression testing”. Maybe it was a parable that was not supposed to be a literal description of the daily programming style. But no matter how it was conceived, soon everything went wrong. And now it is used like a hammer to bring down unbelievers, like a litmus test to declare everyone else unprofessional and unsuitable for programming.
Enough. Enough. My name is David and I do not write tests before writing code. I refuse to apologize for this, let alone hide. I am grateful that TDD made it possible to see automated regression testing in all its glory, but I have long gone from the dogmas of this approach.
I suggest you take a critical look at how this approach affects the integrity of your design. If you are willing to honestly take into account the possibility that this is not absolutely good, then choose a red pill. You may not like what you see after.
So where are we going?
Step One: You must recognize that there is a problem. I think we just did it. The second step is to shift the testing spectrum from module to system. The current fanatical approach to TDD focuses on unit tests, because it is believed that they are able to control the design of the code (the initial rationale for the “tests ahead” approach).
I do not think this is true. The “tests ahead” approach leads to an overly complex structure of intermediary objects and roundabouts, since it is necessary to avoid “slow” operations, for example, accessing the database. Or read-write file. Or run tests in a browser to check the entire system. As a result, we come to the creation of monstrous architecture. Dense thickets of office facilities, teams, and worse.
I rarely write unit tests in the traditional sense of the word, where all the dependencies get wet and thousands of tests can be completed in a few seconds. It just wasn't a good way to test Rails applications. I test Active Records models directly, providing access to a real database. The tests work at the controller level, but I would go further and replace these tests with even higher-level tests forCapybara .
I think this is the direction we are going. Less attention to unit tests, because we no longer use the “tests ahead” approach as a design practice, and more attention to slow system tests. (Which, by the way, does not have to be slow, due to the use of parallelization and cloud infrastructure).
Rails can help with this transition. Today we are not doing anything to encourage complete system tests. We do not have a default tool on the stack. But we are going to fix this flaw. But do not wait until this happens. Try Capybara today and you will have a good idea of where we will be tomorrow.
But first take a deep breath. We are leading our sacred cows for slaughter right now. This is very painful. The TDD methodology is so successful that it is now woven into the identities of a large number of programmers. TDD is not only what they do, it is who they are. We are going through deprogramming to get out of TDD control, and it will take some time.
The worst thing we can do is simply rush into another religion of testing. I can easily imagine a golden calf “only system tests!” Please do not do this.
Yes, for me the “tests ahead” approach is dead. But instead of dancing on his grave, I would rather acknowledge the enormous contribution of TDD. TDD marks an important milestone in our history, but it's time to move on.
Long live the testing.