Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How strict should I be in the "do the simplest thing that could possible work" while doing TDD

For TDD you have to

  1. Create a test that fail
  2. Do the simplest thing that could possible work to pass the test
  3. Add more variants of the test and repeat
  4. Refactor when a pattern emerge

With this approach you're supposing to cover all the cases ( that comes to my mind at least) but I'm wonder if am I being too strict here and if it is possible to "think ahead" some scenarios instead of simple discover them.

For instance, I'm processing a file and if it doesn't conform to a certain format I am to throw an InvalidFormatException

So my first test was:

@Test 
void testFormat(){
    // empty doesn't do anything nor throw anything
    processor.validate("empty.txt"); 
    try {
        processor.validate("invalid.txt");
        assert false: "Should have thrown InvalidFormatException";
    } catch( InvalidFormatException ife ) {
        assert "Invalid format".equals( ife.getMessage() );
    }
 }

I run it and it fails because it doesn't throw an exception.

So the next thing that comes to my mind is: "Do the simplest thing that could possible work", so I :

public void validate( String fileName ) throws InvalidFormatException {
    if(fileName.equals("invalid.txt") {
        throw new InvalidFormatException("Invalid format");
    }
}

Doh!! ( although the real code is a bit more complicated, I found my self doing something like this several times )

I know that I have to eventually add another file name and other test that would make this approach impractical and that would force me to refactor to something that makes sense ( which if I understood correctly is the point of TDD, to discover the patterns the usage unveils ) but:

Q: am I taking too literal the "Do the simplest thing..." stuff?

like image 663
OscarRyz Avatar asked Jun 09 '10 23:06

OscarRyz


1 Answers

I think your approach is fine, if you're comfortable with it. You didn't waste time writing a silly case and solving it in a silly way - you wrote a serious test for real desired functionality and made it pass in - as you say - the simplest way that could possibly work. Now - and into the future, as you add more and more real functionality - you're ensuring that your code has the desired behavior of throwing the correct exception on one particular badly-formatted file. What comes next is to make that behavior real - and you can drive that by writing more tests. When it becomes simpler to write the correct code than to fake it again, that's when you'll write the correct code. That assessment varies among programmers - and of course some would decide that time is when the first failing test is written.

You're using very small steps, and that's the most comfortable approach for me and some other TDDers. If you're more comfortable with larger steps, that's fine, too - but know you can always fall back on a finer-grained process on those occasions when the big steps trip you up.

like image 191
Carl Manaster Avatar answered Nov 17 '22 00:11

Carl Manaster