It is amazing to realize how old the notion of Test Driven Development (TDD) really is. Here are two quotes, that are older than I am, describing the ideas behind TDD :
Report of the NATO Software Engineering Conference 1968:
A software system can best be designed if the testing is interlaced with the designing instead of being used after the design. Through successive repetitions of this process of interlaced testing and design the model ultimately becomes the software system itself. I think that it is the key of the approach that has been suggested, that there is no such question as testing things after the fact with simulation models, but that in effect the testing and the replacement of simulations with modules that are deeper and more detailed goes on with the simulation model controlling, as it were, the place and order in which these things are done.
The humble Programmer, Edsger W. Dijkstra 1972:
But one should not first make the program and then prove its correctness, because then the requirement of providing the proof would only increase the poor programmer's burden. On the contrary: the programmer should let correctness proof and program grow hand in hand. [...] If one first asks oneself what the structure of a convincing proof would be and, having found this, then constructs a program satisfying this proof's requirements, then these correctness concerns turn out to be a very effective heuristic guidance. By definition this approach is only applicable when we restrict ourselves to intellectually manageable programs, but it provides us with effective means for finding a satisfactory one among these.
Today we mostly associate TDD with automated unit-tests and the family of xUnit Frameworks. We associate TDD with writing code.
Yet TDD today is far from being mainstream in my experience. And even teams that decided to adopt TDD are constantly struggling with implementing it in reality.
The participants of the NATO Software Engineering Conference from 1968 probably had quite a different notion of implementing TDD than we have today. Their implementation of TDD was probably far away from the automated unit-tests we strive for today. Yet they had the same mindset that we pursue today.
When Dijkstra was already preaching TDD, the xUnit-Frameworks were not to be born for another 26 years.
In the last few years I have come to the conclusion, that the most important aspect of TDD is the mindset that comes along with TDD.
This mindset is much more valuable than any tool, technology or methodology that is commonly associated with TDD today.
With the right mindset we can practice TDD even in environments where we can't write unit-tests (Lo and behold, I am even thinking of SharePoint Development). TDD does not have to be realized by writing code. Nor is writing unit-test always the best way to implement TDD.
With the right mindset we can even practice TDD with manual testing!
The actual implementation of the test is rather a detail of TDD. Much more important is the mindset of practicing baby steps, the mindset of gaining insights and evolving through rapid feedback, the mindset of leveraging trial & error as a methodology, where errors are not failures but valuable insights that guide the evolution of the project.
This mindset is the reason why children in kindergarden are scoring better than MBA graduates in the Marshmallow Challenge:
And it is our God Complex that prevents us from keeping that mindset.
But when we embrace this mindset, we realize that it is applicable in many other areas than writing software. It is applicable to any goals that we try to accomplish in unordered domains, where the result of an action is literally unknowable. Internet startups are the perfect example for this: In a lot of cases it is he best option to ship something, and then respond to the market reaction. The crucial requirement for this fast-feedback cycle is to establish a "safe-fail" environment, where we can embrace failure and leverage failures to guide us to success.
Steve Freeman writes about Test-Driven Development and Embracing Failure and Obie Fernandez writes about Testing against business metrics that has nothing to do with code.
no! dijkstra doesn't argue for testing, even in your cited part he argues for correctness proofs, you mix up testing and verification. please cite the complete argument three, this is the first sentence:
ReplyDelete"Argument three is based on the constructive approach to the problem of program correctness. Today a usual technique is to make a program and then to test it. But: program testing can be a very effective way to show the presence of bugs, but is hopelessly inadequate for showing their absence. The only effective way to raise the confidence level of a program significantly is to give a convincing proof of its correctness."