Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use TDD when the fix involves changing the method under test's signature?

I'm trying to get my head around TDD methodology and have run into - what I think is - a chicken-and-egg problem: what to do if a bug fix involves the changing of a method's signature.

Consider the following method signature:

string RemoveTokenFromString (string delimited, string token)

As the name suggests, this method removes all instances of a token from delimited and returns the resultant string.

I find later that this method has a bug (e.g. the wrong bits are being removed from the string). So I write a test case describing the scenario where the bug occurs and make sure that the test fails.

When fixing the bug, I find that the method needs more information to be able to do its job properly - and this bit of information can only be sent in as a parameter (the method under test is part of a static class).

What do I do then? If I fix the bug, this compels me to change the unit test - would that be 'correct' TDD methodology?

like image 792
jpoh Avatar asked Apr 08 '09 06:04

jpoh


People also ask

What TDD and how does it work?

Test-driven development (TDD) is a software development process relying on software requirements being converted to test cases before software is fully developed, and tracking all software development by repeatedly testing the software against all test cases.


2 Answers

You have fallen into the most dangerous trap in TDD: you think TDD is about testing, but it isn't. However, it is easy to fall into that trap, since all the terminology in TDD is about testing. This is why BDD was invented: it is essentially TDD, but without the confusing terminology.

In TDD, tests aren't really tests, they are examples. And assertions aren't really assertions, they are expectations. And you aren't dealing with units, you are dealing with behaviors. BDD just calls them that. (Note: BDD has evolved since it was first invented, and it now incorporates things that aren't part of TDD, but the original intention was just "many people do TDD wrong, so use different words to help them do it right".)

Anyway, if you think of a test not as a test, but a behavioral example of how the method should work, it should become obvious that as you develop a better understanding of the expected behavior, deleting or changing the test is not only allowed by TDD, it is the only correct choice! Always keep that in mind!

like image 178
Jörg W Mittag Avatar answered Sep 30 '22 09:09

Jörg W Mittag


There is absolutely nothing wrong with bombing your tests, when you discover that the intended behaviour of the unit changes.

//Up front
[Test]
public void should_remove_correct_token_from_string()
{
  var text = "do.it.correctly..";
  var expected = "doitcorrectly";
  Assert.AreEqual(StaticClass.RemoveTokenFromString(text, "."), expected);
}

//After finding that it doesn't do the right thing
//Delete the old test and *design* a new function that
//Does what you want through a new test
//Remember TDD is about design, not testing!
[Test]
public void should_remove_correct_token_from_string()
{
  var text = "do.it.correctly..";
  var expected = "doitcorrectly";
  Assert.AreEqual(
      StaticClass.RemoveTokenFromString(
          text,
          ".",
          System.Text.Encoding.UTF8), expected);
}

//This will force you to add a new parameter to your function
//Obviously now, there are edge cases to deal with your new parameter etc.
//So more test are required to further design your new function
like image 30
Jim Burger Avatar answered Sep 30 '22 08:09

Jim Burger