Design By Testing

arguably better than DesignForTesting?

By writing a TestFirst, we are designing the shape of the ProductionCode that we are about to write. By definition, we are designing that shape to be testable. One of the criteria for being testable is being isolatable. We can't test something if we can't isolate it. Thus, by writing tests first we are driven to design the production code to be decoupled.

In ObjectOrientedProgramming languages, this manifests itself as simple interfaces that surround the production code. The tests implement those interfaces, supplying the services that the production code needs under control of the tests.

Thus, we test GraphicalUserInterface control code without the GUI. We test database access code without the database. We test hardware control code without the hardware. We have decoupled the system.

Yes you can refactor (after a test fails) to improve the structure.

A failing test does not usually tell us that our structure is bad. It tells us that we have solved the wrong problem. Once the tests all pass, then we can restructure the code while keeping the tests passing.

The tests make it much easier to restructure the code since we can make small changes without fearing that we will break things.

 >> The tests also provide a
 >> lot of documentation about the design and implementation of the
 >> system.

I thought that red herring was resolved a long time ago. Only if the tests themselves are documented or understandable.

And the documents are only understandable if they are documented and understandable. I hate to be facetious here, but at some point somebody has to take responsibility for writing things that people can understand. Why not the programmers? Why not the tests?

In any case, reading a test can tell you a *lot* about the expectations of the programmers who wrote it.

Is documenting tests one of the things done? (before or after writing them? If before, would you call that Documentation Driven Test Driven Development, DDTDD or put more simply WaterFall? If after, pick your own term)

Consider the following test (drawn from a real project I am involved in):

  public void testWikiWordRegexp() throws Exception
  {
    checkWord(true, "SimpleWikiWord?", "WikiWord");
    checkWord(true, "ThreeWordWikiWord?", "WordWordWord?");
    checkWord(false, "DoubleCapitals?", "HelloDDouble");
    checkWord(true, "Initials", "RcM");
    checkWord(false, "Hello", "Hello");
    checkWord(true, "many words", "WikiWordWithManyWords?");
    checkWord(true, "dot separated", "WidgetRoot?.ChildPage?");
    checkWord(true, "three level", "GrandPa?.FatheR.SoN");
    checkWord(true, "Dot at start", ".RootPage?.ChildPage?");
    checkWord(false, "Lower case at start", "lowerCaseAtStart");
    checkWord(true, "SubPage", "^SubPage");
    checkWord(true, "SubPage Multiple", "^SubPage.SubPage");
  }

OK, now you don't know anything about the program it is testing, and you don't know anything at all about the structure of the code. What can you tell from this test -- anyone?

-- RobertCecilMartin on news:comp.object


EditText of this page (last edited March 4, 2004) or FindPage with title or text search