Domanda

My understanding of how TDD should work is that you write a failing test for the next bit of functionality you want to add to a function or object, code until the test passes and then write the next test. Is it ever ok to write tests that pass with the code as is?

One example of that happened today. I was writing a function that could Manchester encode an arbitrary number of bits. I wrote failing tests for encoding one single bit and coded until it passed, then wrote a failing test for passing two bits to the function and coded until it passed. But the solution I used to handle two bits made the code work for any number of bits. Because passing a byte to the function will be it's most common use, I added a unit test to make sure it worked for 8 bits, which did in fact pass.

Did I violate TDD principles? Is there anything wrong with adding redundant tests just for my peace of mind? I understand part of the problem is that I could have written a faulty tests and would never know because it didn't fail in the first place, but I'm not sure what the alternative is.

È stato utile?

Soluzione

The main reasons for using TDD are to make sure every bit of code you write is at least minimally exercised by the test suite, and that your API is well-usable for the application programmer.

Writing an additional test for a case that already passes doesn't increase coverage, and it doesn't change the API any further, so neither of those reasons apply - the test doesn't add any value in these respects, but it certainly does not harm either. It just takes up time to write that you might have spent doing something else.

Nevertheless, it's perfectly possible to have algorithms that work on simple cases and even look as if they were completely general, but in fact aren't, so there is nothing wrong in principle with adding another test case for N=8. In a perfect world you might have thought about that case right away and written both tests before coding the solution, but doesn't really matter very much if you add it afterwards - you've still fulfilled all the princples that people want TDD for.

(There are those who demand that you write exactly one test case and then exactly one bit of code, and that every test tests exactly one thing, i.e. that every defect in your code base would trip exactly one test. But I see no added value in such exaggerated cycle-observance.)

Altri suggerimenti

If the test is covering behaviour that is valuable, and you want to guard against regressions, then it's a perfectly good idea to write it 'after the fact'.

Imagine that someone else had already written the code without tests. You wouldn't be asking whether it's a bad idea to add tests to existing code.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top