Reputation: 443
I'm working on a project in which for the first time I applied TDD methodology. It all went pretty well until there were requirements changes and I had to change some classes behavior and API Changing one class behavior eventually led to changing a few others. I didn't know how to start this process from the test side, so I started changing the code. I ended up with lots of compilation errors in the test code and after I fixed them some did not pass. But the thing is, I don't even know if the tests cover what they used to cover before. When writing, I added production code piece by piece as I added tests, but now it seems like I have to go over all the test classes that changed and verify:
TDD is supposed to give me a safety net while refactoring. Isn't it? As it currently appears in my case it doesn't give me that.
What am I doing wrong? Is this the way to do such refactoring work or is there a better approach?
Upvotes: 0
Views: 125
Reputation: 3666
A) Refactoring: improving the structure of the code WITHOUT modifying its externally observable behaviour. (Here external means external to the component under test)
Since you say that you were modifying API, this implies changes to the behaviour, so what you were doing wasn't refactoring. That's not a criticism, just an observation.
If you are truly refactoring (not changing the externally observable behaviour) then the tests should not need changed. If they still need changed, then they are too tightly coupled to the implementation of the component (as opposed to its behaviour).
B) In hindsight, can you now see how you might have driven these changes from the test side? Did you fully understand the requirement(s) that drove the changes?
I consider automated tests to be system documentation. If the requirements change then I look for the part of the documentation that's being affected and change it to reflect the new requirements. The tests will then most likely fail, but now I have the driver to change the implementation. If they don't fail, then maybe all is good ;)
C) If you found yourself making the same changes in multiple places in your tests, maybe you should apply the DRY (Don't Repeat Yourself) approach. Localise the functionality provided by duplicated pieces of code in a single place (class/method). Utilise the Builder or Object Mother patterns to insulate your tests from incidental changes to data structures.... and so on.
Upvotes: 2