views:

141

answers:

6

I have a project that I am building that I have to change a method to behave slightly different. I have several unit tests already built against that method, but I will need to add more to cover the new behavior I am going to add to it. Is it good form to change/add those tests first before making the code change, or do you change your code, fix the broken tests and add the new tests to cover the new behavior?

+6  A: 

It is better to update the tests first and let them fail and then go back and update the code until the test passes. A.K.A Test driven development or Test first development.

leonm
+13  A: 

If you're to follow TDD practices, you should update your tests first. You'll have broken test cases that should hopefully get fixed when you fix your code.

Ates Goral
s/hopefully/definitely/
William Pursell
The word was chosen with intention :)
Ates Goral
A: 

What I do is code first and then create tests after. Since you could have a case where you program your test to work in some way and then when you code you realize you can't do that. So you'll need to change the tests again.

Ólafur Waage
In my experience, this leads to the tests being biased towards the code written, rather than the requirements. Writing the tests first is the best way to get proper tests, and proper tests are very helpful in getting correct code.
David Thornley
They can be yes. So it's something I look out for. What I test is all code paths.
Ólafur Waage
Writing tests after code carries the implicit assumption that the code is correct. If this is your assumption, writing the test is a waste of time. In trivial cases, this may even be a safe assumption, but a) I assume you're dealing with a lot of non-trivial cases in your daily work, and b) if the code is that trivial, writing tests for it is probably not a wise use of your time.Writing tests first *defines* correct behavior, rather than rubber-stamping a "PASS" after the fact.
bradheintz
+3  A: 

If you are doing test first development, at a minimum you have to write a new test that justifies the change. The change could then break the old tests and you could fix them after you see them fail, if the change is incidental to the test. If, however you know that the test used to test for the old behavior and it just needs to change for the new behavior, there is no reason to not just change that test instead of writing a new one.

It isn't worth the effort (in my view) to figure out which tests are going to break with the change and change them all first because the test runner will tell you that after you make the change.

EDIT (in response to comment): I prefer writing the test first, but that is the TDD style. In that case the test drives design. There is also a rythm and pattern to that kind of development (red-green-refactor). The other way around is more the pure unit test way, you already designed and implemented what you want, now you are testing it. There is nothing wrong with that, it is a different development approach and the choice doesn't depend on the existence of other tests. It is really a development approach in general.

Yishai
Im my particular case, the old tests should all still work as they are written. I am simply adding an additional set of functionality to a particular method that is not triggered by any existing test, so I have to write new tests to cover that. Would you write those tests first, or make the change and then code the new tests? I am taking for granted that all the old tests should all still work.
Jason
The good news is, you don't have to take it for granted - you can run the tests.Because I find the TDD process useful in my own work, I'd suggest writing the tests first - quantitatively define what you want the code to do before you implement. See my answer for more detail.
bradheintz
A: 

I personally prefer writing the functionality first and then doing the unit tests (if appropriate to the specific functionality). If it's something that doesn't really worth unit testing I usually skip it. I have found that, it's usually a waste of time to add unit test to all code that you write. There certainly are place where it's very useful to have it, but that hardly extends to all your code.

It's easy to spot the wasted productivity when you refactor something, and realize that you have broken half the unit tests that don't really add any value to begin with; since a fault would have been easily spotted in the first place. So all that effort is a waste of time. If you work in an environment where there is no incentive to deliver fast and adapt quickly, then I guess having tons of unit tests is feasible. Otherwise, you just increased your costs by a whole bunch without adding that much more value to your users.

Mircea Grelus
If you break half your tests, you're not refactoring; you're making functional changes. Refactoring does not change the observable behavior of the software.
bradheintz
+2  A: 

I'll admit that I sometimes cheat. If a change is simple enough that I can know the outcome with certainty, I will sometimes change code, then tests. Like if I'm multiplying one number by a constant, and all I'm doing is changing the constant, I'll go ahead with the change and update the test case afterward.

If you're doing anything even slightly more complex, though, I'd advise sticking to the TDD orthodoxy and change the test first. Define what you want to do before doing it. Also, I'd recommend putting new tests after pre-existing tests, so that tests related to existing functionality that you want preserved are run first, assuring you that you haven't broken anything (or alerting you as early as possible that you have).

bradheintz
+1 for honesty and pragmatism.
Carl Manaster