(I normally only post in one language depending the circumnstances, but this IsTDDDead thing is big enought write in both spanish and english)
There is much buzz lately by the statements and blog posts of @dhh (creator of Ruby on Rails) about is TDD Dead?
This has led to some interesting conversations between @dhh , Kent Beck (creator of XP and TDD and eminence in the industry) and Martin Fowler ( eminence in the industry) about it.
Martin Fowler created a page dedicated to this hangouts: http://martinfowler.com/articles/is-tdd-dead/
While not finished, this series of lectures have been incredibly productive for me.
@ Dhh basically states that TDD applied in strictest manner (not even single line of production code should be written without the test first) leads to various problems:
• Test Induced Damage: design decisions that leads to decoupling components for the purpose of mocking. @Dhh thinks that the “over” decoupling for mocking causes “worse” and less understandable code
• Developer overconfidence: The fact that applying TDD the developer feels it no longer has to test your code in an exploratory manner
Kent Beck explains that TDD should be applied whenever possible, especially when we have clear input / outputs, but that there are parts of systems that feels unnatural and it is best to proceed creating tests afterwards. Fowler agrees to this argument and said that is what he uses.
He also explains that most Test Induced Damaged problems are not caused TDD itself, but by the method as Folwer calls “mockist” in which tends to decouple (sometimes too much) in order to test in isolation. In his excellent article http://martinfowler.com/articles/mocksArentStubs.html Fowler explains the differences between the “classical” approach and “mockist”. The “classicist” tries to mock less and performs more tests might be called “integration” (I will later clarified this). The “mockist” tries to test everything in isolation. The article explains the advantages of both , being the major disadvantage of the “mockist ” method, that the test code is more coupled with the production code and refactoring it (without changing the functionality, obviously) can break tests that should not. In any case, he explains that he knows excellent developers using the “mockist” method effectively.
Martin Fowler recently published an article in which http://martinfowler.com/bliki/UnitTest.html explains the definition of “Unit “. He states that he (and others) were criticized at the time by considering that unit is not necessarily a method or class. The Unit may be a set of classes, methods group or whatever the team who knows the problem can be considered unitary. This fits the “classical” approach I mentioned before.
We can draw some conclusions about the hangouts:
• ALL of three agree that the most important thing is to have SelfTestingCode and TDD is a way to get there.
• They also agree that creating tests in which Mocks return mocks is probably wrong and would lead to problems.
• We must be aware of the “classical” and “mockist” advantages and disadvantages
• Both Kent and Fowler are prefer “classic” approach
• TDD is not dead. It’s very, very effective and positive in certain situations. Depending on the problem and people can (should? ) use most of the time
• The fundamentalist TDD is one that can cause problems. Sometimes depending on the flow of development is not suitable for TDD. But like everything, depends on many factors and there are teams that can do it without problems.
• The definition of “Unit” does not have to be class or method. It is a team decision what the unit is.
In my personal opinion, I think @ dhh is perhaps somewhat extreme, but all the dialogue itself is very, very positive. I think that he is right in the sense that “fundamentalist” TDD can lead to the problems described. We must NOT apply “Fundamentalist TDD”. In general I do not make strict TDD and whenever I don’t “I felt bad”, thinking I’m doing something wrong. However the words of @dhh, Beck and Fowler lead me to see that it is completely natural. Yes, you need to try using a TDD approach, try starting the problem we are solving as a series of inputs and expected outputs (and unexpected). But when the “flow” of the solution does not permit it, we can proceed without TDD. The important thing is to have SelfTestingCode
In any case, I think that the most positive thing is watching that 3 industry giants may have their disagreements exposing their views, reminding us once again that there are many ways to make good software. The important thing is knowing all the opinions you can in order to make good decisions. And once taken a certain way to be consistent with it. Mixing 2 good solutions not always leads (I repeat NOT ALWAYS) to a better solution. Hence the importance of standards and coordination within a development team for them to follow a unified view on the general aspects of software architecture.
These are other interesting links about all these topics:
I’m looking forward the next hangout (the fourth)