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?
views:
141answers:
6It 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.
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.
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.
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.
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.
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).