Unit tests makes it harder to refactor code
During my recent brownbag on TDD one comment was that having a lot of unit tests makes it harder to refactor code. First of all the word refactoris in my opinion misused as much as mocking. There is a difference between refactoring and rewriting. Refactoring means you change the code to be "better" without changing any functionality. Rewriting means you potentially change things completely including changing interfaces in APIs. So first of all, if you refactor your code and that means you have to change your unit tests your unit tests are too tightly coupled with your code. Lesson learned; somebody screwed up when writing the tests in the first place. This happens all the time when you learn TDD. It is just a matter of biting the bullet and learn form the mistake you made.
So back to the original statement; it should really be unit tests makes it harder to rewrite code. Think about it. You want to change an API and some functionality and as a result of that you have to update hundreds of unit tests. That's a big pain right? But wait... All these tests that now fail means I have manually verify that things I didn't want to change still works and things I wanted to change are changed to the correct thing. That is all good isn't it? All the failing unit tests are really like a buddy asking; Did you really want to change this? Is it really a good idea to change this? Consider the alternative with no unit tests... Sure you don't have to "waste time" updating old unit tests but neither do you know if your code works as expected.
So if you're ending up changing tests when you refactor code; somebody screwed up. And changing unit tests when you rewrite code is a good thing!
Comments
Anonymous
August 21, 2010
Good unit tests are atomic, so if a change surface is small and code written following SOLID principles etc. the number of tests shouldn't be large... Other then that small comment, +1Anonymous
August 21, 2010
I've heard that, too, but I think that any pain you feels when "refactoring" your code is more of an issue with following good programming principles than the fact that the code is wrapped in unit tests. If one's not following good programming principles like the Open Closed Principle or Single Responsibility Principle, changing your code is still incredibly easy because each change probably won't go beyond one or two small classes. And if the change is substantial, you can simply eject the old code and tests and start new, pulling in whatever small classes from the old code that you can. After doing TDD for a while, I've learned that it's not enough. It's essential, but I've seen/written some big messes with TDD. But when coupled with following principles like SOLID, you'll really see good results.Anonymous
August 23, 2010
I have to wonder how you structured your code, and your tests for this to happen...Anonymous
August 23, 2010
...for what to happen? Easy or hard to refactor? :-)Anonymous
August 23, 2010
The comment has been removedAnonymous
August 23, 2010
Agreed! But I think you could change the title a little bit. I came to the site thinking that you were actually complaining about TDD. Nice post, btw!Anonymous
August 23, 2010
@Gregorio: maybe that was the point... :-)Anonymous
August 24, 2010
You can choose which unit tests to keep and which not. I usually keep higher level tests.