views:

114

answers:

6

I have been trying to stick to the TDD approach. So I have made some tests and they all fail. Now I am implementing. But now that I am implementing I have seen that the methods are too simple to fail. In particular I have implemented the observer pattern and all that happens is that I notify all the registered observers. So use a for each loop and call notify. This certainly sounds too simple to break. Now that I have the tests in places should I delete them? This also seems to be a bit of a waste of time. So should I try and anticipate methods that would be too simple to break?

+8  A: 

No.

The methods may be too simple to break right now, but that doesn't mean they'll never need to be modified (and possibly broken) in the future.

Binary Worrier
Thanks for the comment. Then should I rather leave them for now and Add them later if the method changes. Obvious danger is that you forget to update the unit test. BUT even when making changes we should first have to write a unit test for the change so we should catch it.
uriDium
Leave the simple test there, if the method needs to change, and it's a breaking change, then you'll need to modify the unit tests. However, if it isn't a breaking change and the tests stop working, then there's a bug in your change.
Binary Worrier
+3  A: 

You're saying this is too simple to fail:

for (i = 0; i < observers.length; ++i) {
    // Notify observer observers[i]
}

It's tempting to think that, but consider this common mistake:

for (i = 0; i <= observers.length; ++i) {
    // Notify observer observers[i]
}

Or this one:

for (i = 0; i < observers.length; ++j) {
    // Notify observer observers[i]
}

Or maybe observers aren't getting added correctly. Or...or...or...

If you already have the tests, it seems unnecessary to remove them, and one axiom of software is the functions tend to grow over time, so what's simple now may be less so down-the-line -- exactly the kind of thing your tests are supposed to help you with.

T.J. Crowder
No a For Each statement. The For Each statement is a language construct so it is essentially RE-testing the compiler. If it were a normal loop with int i = 0 etc then I would.
uriDium
@uriDium: That's fine (you didn't indicate what language or construct you were using, so I went with a common denominator). The point still stands; virtually nothing is too simple to get wrong somehow, and functions tend to grow in complexity over time.
T.J. Crowder
@T.J. I agree, there may be no point testing foreach, however you're also testing the iterator block, whos to say that won't chage to be a custom iterator, it should of course have it's own tests, but whos to say this foreach won't find something those tests missed.
Binary Worrier
Similar to what Binary Worrier said, it may feel like re-testing For Each today, but tomorrow a requirement may turn up that causes the maintenance programmer to change the implementation to a for or while loop or whatever. The test provides confidence that the change in implementation hasn't resulted in a change in behaviour. Sure, the maintenance programmer could go, "Now it's more complicated, I'll write a test" -- but that doesn't tell him what aspects of the current behaviour he needs to test *for*. Having the test already in place does.
itowlson
Suppose, say, that one of your Observers responded to its notification by deleting another Observer. This test would then generate an error - and it's an error that would be hard to debug without this test. Nothing is too simple to break.
Carl Manaster
+3  A: 

Yes; If you're testing the functionality of the underlying compiler/virtual machine, your test is too simple. Unless, that is, you do not trust that particular piece of the compiler/virtual machine that is being exercised.

But, of course, the reality of tests is a bit more complex than just a yes/no answer to this question. As noted in another answer, if you have already written the tests, don't delete them. But you also should not use them in a code coverage context as an argument for confidence.

Steen
+2  A: 

No.

You're doing it exactly right: writing tests that fail first, then fixing them. Leave those tests alone, write more complex ones in the future if you think you will need them (eg to reproduce bugs).

Gerrie Schenck
+2  A: 

The more tests you have, the less pain you're gonna have in the future. Nevermind their simplicity.

Kerido
A: 

Now that you've gotten all those tests to pass leave them alone. If they're running quickly enough they won't be a burden to anyone.

However, in the future, you may want to write just one failing test at a time. (See The Three Rules). This is because it will allow your design to improve while you are developing your code.

When you had all your tests failing and no implementation you had fixed your design and now its working you may be loathed to refactor the design to improve it.

I also suspect that you had a tricky time implementing your code as each implementation step might have broken more tests than it passed, but hey, I'm only guessing!

quamrana