in Search

cruizer

aspiring to free and open the mind of .NET developers

Why tests should be made to fail first, then pass later

Because it's better than having tests that pass first then fail later. Stick out tongue

No kidding. This is true. At first I couldn't understand why TDD evangelists would say that a test should start at "red" (or even fail to compile at all) before you put in code that will make the test pass or go "green." I mean, it's a waste of my time, isn't it? I know what I need to do and I don't need to go through this red-then-green sequence when I can go to green immediately.

It was only recently that I realized why: because a test that passes at first try doesn't give you (as the programmer) confidence that the code is behaving as you intended. It might have passed by sheer serendipity or by the way the test was constructed. On the other hand, failing a test first means you know what you need to accomplish (pass the test) and that your code (under test) lacks the thing that will make it pass. So once you finally get it to green, it means that the code you've put in yields the correct behavior. And taken together with the previous test cases (which should still be green, of course), it means that the code is on its way to correctness.

I shall demonstrate how I came to this realization with sample code in my next post. For a change I'll use PHP for the demonstration. I've come to realize too that PHP needs test-driven code more than anything else, because of its loose and typeless nature. More on that later!
Only published comments... Jan 15 2007, 05:26 PM by cruizer
Filed under: ,

Comments

 

bonskijr said:

IMO, anyone new to TDD hear it's mantra(Red-Green-Refactor) will be put off by the "Write a failing test first"(Red). Say what?!

This first step(Red) I think, is a critical reason why most developers doesn't want to do TDD(I didn't at first). I mean, why would you want to write a failing test? Shouldn't it be "Write a test w/c expresses what you expect from your code?"

Case in point, say you want to test a Sum function, a newbie following write a failing test would naively write this one:

[Test]

public void SumTest()

{

  Calculator total = new Calculator(5);

  int result = total.Sum(5);

  Assert.AreEqual(5, result);

}

--

The preceding will fail because of either:

1.) Calculator class has not yet been created

2.) Sum method is not yet created

2.) or if 1 and 2 are true, it will fail because  5!=10

I've accomplished, Red(failing test), now I have to make it Green(passing), what I do is change the: AssertEqual(10,result); and it will pass. Being a newbie at TDD, I've committed several mistakes:

1.) I didn't follow that, a test shouldn't be altered(only if it's a wrong test), alteration should be in the code to be tested.

2.) The first iteration of test itself doesn't make sense, why would I assert 5 == 10? Coz, I want to make a failing test, that's why.

It should've been written as Assert.AreEqual(10,result); in the first place.

I'm writing this rather lengthy response, since this are the steps I was doing before and had to force myself to make sense of my tests. It was the later iterations of my venture to TDD that made me realize why it shouldn't be a "Make a failing test" and the book "Refactoring to patterns" further clarified it to me(newbie TDD practioneer) that "Red: You create a test that expresses what you expect your code to do."

January 15, 2007 3:13 AM
 

cruizer said:

If you've read my previous post s here, you'll notice that I advocate code testability and TDD. One of

January 18, 2007 6:14 PM
 

cruizer said:

I made that observation, while doing PHP TDD-style, in my previous post . In this interview with Dave

April 9, 2007 6:47 PM