Testing: The Art of Iterative Development | Day 7
As our final day on the Ruby language, we further engaged in a discussion on the nature of Test Driven Development (TDD). The difficulties and sheer counter-intuitiveness of this approach for the beginner cannot be understated – it is difficult, plain and simple. To learn the philosophy of TDD is quite nice, but to actually engage in the process of its enactment is a case study in frustration. Naturally, one desires genuinely to write code immediately so that a foundation of functionality is attained; to write the test first feels, initially, like an obstacle. Nonetheless, deep down, I understand this to be a necessary behaviour to be acquired by the developing programmer.
The frustrated beginner must ask himself: to what extent have all techniques in life been truly intuitive? And further: if these techniques were not intuitive, did they not help one achieve maximum efficiency in a given domain? Having participated in fencing for half of my university career, after a lifetime in karate, I can think of no better example than a simple lunge. In karate, we are taught to lead with our base and then follow through with our strike; in fencing, we extend our arm first before engaging in the lunge. Although it seems counter-intuitive, it is the optimal approach should one desire to gain points in competitive fencing – the behaviour is optimized for its particular context. Likewise, although TDD may seem counter-intuitive for the amateur programmer, it has its merits in the context of a company devoted towards the production of reliable code. Moreover, the fact that Ruby is an interpreted language means that the tests that we write are truly the only filter gauging the quality of our code – there are no compilers here! It is what it is: I can live with this process if I was working in a development shop but I would absolutely not use TDD if I were building the prototype for a startup that hasn’t yet begun customer development and is still engaged in discovery mode.
Hindrances aside, TDD has its merits when truly mastered. The process forces a ruthless minimalism upon its user, who must build progressively at the most atomic level. Moreover, as having a well-defined scope allows you to write essays with relative ease, TDD permits you to write code, incrementally, into clearly defined project milestones, building the structure of your program code-brick by code-brick, so to speak. The tests are not so much blueprints as they are design specifications; however, rather than laying out the specs in their entirety from the get go, you’re incrementally specifying the needs of the structure, taking the environmental and topological contexts into close consideration every step of the way. In many respects, TDD is the epitome of a personal philosophy that I hold near and dear: freedom through restriction.
The blank page is awfully intimidating for the unseasoned writer, just as the blinking cursor of a new tab in Sublime Text 2 is for the emerging web developer. How does one resolve such uncertainty? For the writer, it may help to break his writing project down into its elemental structure – we’ve all gone through the process of identifying the introduction, thesis, body arguments, and conclusion. In an analogous sense, TDD does the same thing for the web developer. In short, with TDD there is much gold hidden in plain sight – while the beginner trifles over the barrenness of the surface, the adept digs just a little deeper and remains masterfully content. Benefit accrues to those who conduct their present affairs in the context of a long-term vision and TDD is an optimal development framework for writing code that withstands the impact of inevitable obsolescence.