When you do TDD, “fake implementations” or “wrong code” are OK, as long as they pass all the tests you have so far.

But when do you stop to fake? When do you start writing “real code”?

There’s a rule that helps you decide: The “Specific / Generic Rule”.

Intro (TL;DR)

You are watching part 7 of a series on the first two phases of the test-driven development cycle, “red” and “green”.

In the green phase, you must take care not to implement too much functionality. It’s often better to just fake it and leave the real implementation for later. But for how long can you postpone the real implementation?

In today’s video, I want to show you the specific / generic rule. It will help you decide when and how much to fake your implementation when you do test-driven development.

My name is David, and I teach TDD and agile engineering practices. By the way, if you like this video, please share it with your friends and followers.

Question / Problem

Just as in the last 6 videos, I am implementing a “hangman” game. And I am writing tests for how the program should display a placeholder at the very beginning of the game.

Tests one and two

My first test: The game should show a single underscore when the word to guess is “a”. My first implementation is completely fake: I return a single underscore.

@Test
public void hintIsSingle_WhenWordToGuessIsA() {
  Hangman hangman = new Hangman("");

  assertThat(hangman.hint()).isEqualTo("_");
}

As a second test, i check whether it returns two underscores when the word to guess is “to”. I can still fake the implementation, adding an if.

@Test
public void hintIsTwo_WhenWordToGuessIsTo() {
  Hangman hangman = new Hangman("to");

  assertThat(hangman.hint()).isEqualTo("__");
}

public class Hangman {
  private final String secretWord;

  public Hangman(String secretWord) {
    this.secretWord = secretWord;
  }

  public String hint() {
    if(this.secretWord.length() > 1) {
      return "__";
    }
    return "_";
  }
}

Code for tests one and two

My third test is “returns five underscores when the word to guess is hello”. What now? Should I add another if? Or should I add a loop, which would turn into the real implementation?

@Test
public void hintIs5_WhenWordToGuessIsHello() {
  Hangman hangman = new Hangman("hello");

  assertThat(hangman.hint()).isEqualTo("_____");
}

Tests one, two and three

Solution

The specific / generic rule helps me answer this question. It says:

As the tests get more specific, the code gets more generic.

Tests one and two

After every Red-Green-Refactor cycle, the implementation should be more generic than before. The “if” after the second test was more generic than returning the literal string after the first.

Now, after the third test, another “if” would not be more generic. Neither would be a switch in this case. But I could continue with a loop. This is more generic and brings me closer to the real implementation.

I could also change the implementation to a regular expression now, because that would also be more generic; but maybe too big of a change during getting the test to “green”. I could leave this as a future refactoring step.

Conclusion

When you ask yourself: “How long can I fake it? When should I ‘start’ the real implementation?”, the “Specific / Generic rule” can help you find the answer.

It says:

As the tests get more specific, the code gets more generic.

Focus on pinning down the final implemenation by adding more and more specific tests, and make sure that the production code becomes more generic with each green test.

CTA

Did you know about the specific / generic rule? Are you using it? If not, how do you decide when to “stop faking it”?

Please tell me in the comments of this video or on Twitter, where I am @dtanzer.

And if you liked this video, please subscribe to my channel and share this video with your friends and followers - That would be awesome!

Read / watch all parts of this series here: