# Wednesday, February 06, 2008

What is TSD or Test Supported Development?

TSD is a more moderate Software Development methodology than Test Driven Development (TDD). The label "Test Supported Development" (TSD) intends to characterize the creation of tests during ANY/ALL stages of development, that is, in TSD, tests are not necessarily created before their System Under Test (SUT), but not necessarily created at the end of development, either.

In a sense, TSD is a Software Development Design Pattern. One definition of a design pattern is as follows: A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in object-oriented systems. Here's another definition: A design pattern is a general reusable solution to a commonly occurring problem in software design. A design pattern is not a finished design that can be transformed directly into code.

How is TSD different than Unit Testing / Automated Testing?

Where TDD is always Test-First and Unit Testing is traditionally Test-Later, TSD is a mixture of the Test-First and Test-Later approaches. Unlike "Plain Old Unit Testing" (POUT), TSD does recognize value in a Test-First approach, just not a Test-First-ALWAYS approach. POUT is, however, a natural subset of TSD.

Do we really need another Testing-Related Acronym?

There is value in the TSD design pattern in that it recognizes the value of Test-First Software Design WITHOUT being tied to the arguably dogmatic, but certainly all-or-nothing Test-First-ALWAYS approach that TDD practitioners professes. TSD is not a NEW development methodology, but a conceptual marriage of Testing As A Design Methodology and Testing As A Support Mechanism. It is a moderate approach to Test-First Software Design that acknowledges its value without adopting Test-First as its core tenet.

Why aren't you on the TDD bandwagon?

TDD, especially when coupled with 100% code coverage, can be expensive, sluggish, and awkward. A moderation or balance more in the spirit of the 80/20 rule is apt to produce a better Return on Investment (ROI), assuming time to market is important. For example, hit the core/complex/critical code the hardest, with some tests driving/exploring interface design, but with much code just following established OO design idioms, such as DIP (a.k.a. Inversion of Control or IoC), SRP, OCP, LSP, ISP, etc., if / when appropriate.

TDD takes the wonderful concept of Test-First Software Design and chains it to a dogmatic mantra of Test-First-ALWAYS.

But TDD goes with Agile like peanut butter goes with jelly (in the U.S., anyway), so, are you saying that Agile is bad?

No, I like Agile, but again, in moderation. For instance, I believe in the principle of YAGNI and I feel that Big Design Up Front (BDUF) is often brittle and therefore tends to bring lower ROI. However, I think there can be significant ROI in architecting a few parts of the system "up front" that are obviously required (I can hear a chorus of Agilistas scream "Heresy!" after that statement). And yes, I must clarify that one should be careful that this obviousness is a collective (or at least collectively agreed upon) obviousness, and not just, for instance, an architect's speculation. Simply stated, starting out with some Technical Capital** helps to avoid some Technical Debt. TSD fits well with this moderate approach that some up front design can produce significant ROI. Conversely, TDD primarily fits well with only a textbook-Agile approach.

But TDD enforces good OO design idioms, such as IoC! And ummm...

Indeed, since DIP is at the heart of the Top-Down approach of TDD, it does incidentally enforce IoC, but that comes at the price of potential overhead. Given most unit testing frameworks, effective TDD requires interfaces to be extracted out of / pre-designed into the SUT for the purpose of Mocking / Stubbing SUTs that have yet to be implemented, or potentially slow-processing SUTs that need to be bypassed for quicker testing feedback loops. This proliferation of interfaces will likely increase maintenance cost.

TypeMock seems to offer a shortcut around these interface extractions, but some TDDers might feel uncomfortable with the power of such a shortcut as it is incongruent with their valuing of TDD's IoC enforcement.

Developers should be free to choose to apply OO design idioms AS THEY SEE FIT. Obviously, good object-oriented design, refactoring, etc. is not exclusively the domain of TDD. Also, I would wager that if developers really wanted an IoC enforcement tool, they would prefer to go searching for (or create) just that, instead of having it forced upon them as part of a Development Methodology. In fact, a "Design Principle Enforcement Tool" might not be a bad idea, assuming it does not yet exist.

So why is TDD so popular, then?

I believe that TDD is popular due to its promise (whether stated or perceived due to wishful thinking) of significantly higher quality software and equally as important, its prescriptive nature. By prescriptive, I mean in order to do TDD, just do A, B, then C and viola, you're doing TDD. I am TDD, you can, too! Prescriptive advice is very attractive, especially in an industry that caters to a scientific mindset. Combine a methodology that promises (perception is everything) something that has been an extremely evasive / expensive outcome to date (quality software) with a set of steps that are reasonable to learn and reasonable to repeat, and an uprising of excitement will likely follow. As will sales of related books and training.

Even I can recognize and appreciate that TDD has been a great catalyst for progress in the never-ending search for a Development Methodology that assures a reasonable quality piece of software with a reasonable amount of effort. Personally, I don't doubt the value TDD has in flushing out bugs, fleshing out APIs, etc.

However, I'm still unconvinced it has a higher ROI than TSD as a project's exclusive (or maybe even primary) development methodology. Also, if your development methodology is not Agile (specifically, I mean heavily incremental & heavily refactoral), I'm convinced TDD has an even lower ROI potential.

Why use TSD?

Use TSD because of its increased ROI over TDD. TSD recognizes, as in many life concepts, that moderation and experiential discernment are key. There is a reason that the "80/20 rule" (Pareto Principle) has withstood the test of time.

TSD is a design pattern that will help good programmers write better code. TSD is NOT prescriptive. Prescriptive advice implies a cookie-cutter mentality. TSD will NOT make your code great if you suck as a programmer. And let me tell you a dirty little secret -- neither will TDD, regardless of what many might hear or hope! Something does not need to be prescriptive to have significant value.  N-Tier Architecture is not prescriptive.  Unit Testing is not prescriptive. Domain Driven Design is not prescriptive. The list goes on. Also keep in mind that Design Patterns are not entirely prescriptive, either, even though many people may use the textbook example of a design pattern as if it were prescriptive.  However, the heart of a design pattern is as a problem/solution concept under a easy communicated moniker.

What proof do you have that TSD is better than TDD?

The same proof that TDD was better than any other development methodology when it was first introduced.

If you found this post helpful, please "Kick" it so others can find it too:
kick it on DotNetKicks.com

** I was not the first to coin the term "Technical Capital" (dammit), but as I came up with the concept independently, my meaning is different than the one here, since Jan is referring to building technical capital through subsequent iterations, not through "up front" design.