Question

I was recently part of a TDD development team. At certain point I realized that there is a design mistake instead of Object Oriented Design and Structural design the problems were solved via statuses. Tens of statuses. For a brief moment I thought - Hmm... maybe I can actualy try to do some modeling and reduce the statuses. But I realize that the amount of generated Unit tests that relay on these statuses is so tremendous. At that point I lost all motivation to actualy perform the change.

If there is fundamental weakness in solution but the TDD cycle is already to far gone in the development. How do you do design change in TDD when you have such huge amounts of test that may be dependent on the existing implementation?

Was it helpful?

Solution

How do you do design change in TDD when you have such huge amounts of test that may be dependent on the existing implementation?

First, the best approach may be to avoid running into this situation at first hand, and refactor earlier. Often people forget that refactoring should be done rigorously in each TDD cycle, and design flaws should be removed as soon as they become apparent. Given there are so many tests as you said, I am pretty sure the design flaw could have been spotted much earlier, at a point in time when there existed a lot fewer tests.

But what can you do if you have already painted yourself into that corner? The problem here is usually the amount of test code which uses the public-facing API of the Subject-Under-Test, which is what you want to change. So as an approach to resolve that problem,

  • try to reduce the number of direct test calls to the public API by refactoring the tests themselves first and make them more DRY.

  • build an anti-corruption layer, or a facade, or a proxy between your tests and the SUT, so you can change the API of the SUT without having to change too many parts of your tests. That will allow you to keep the tests as they are for now. Later, when you have some time for cleaning up, you may decide to migrate the tests to the new API one-by-one.

The latter approach is also known as strangler pattern and can often be used to gradually swap out legacy components by components with a new design, not only for tests.

As an example, if you have 50 tests calling the same public method of a class (and maybe only one or two places in your production code calling the same method), then the tests seem to hinder you changing the signature of that method. But if most of the direct calls inside the test code are rerouted through a single helper method, maybe one which also does parts of the arrange-act-assert work, it will become a lot simpler to change the method signature of the SUT.

OTHER TIPS

I saw the same problems when trying to do TDD. I think the solution is as simple as doing TDD when it makes sense and not dogmatically all the time.

When the requirements are clear, or when fixing a bug, it makes sense to write a test first. You will know when you're done, you can reproduce the problem, etc.

But when you design something that you'll likely need to iterate a few times, TDD is just an anchor. Also, there is a trade-off between having tests for everything and speed of change for the long term. If you have too few tests, you'll have no safety-net, but having too much tests cements everything in place. I think there's a balance somewhere between those extremes.

In summary: I saw the same things as you. If you already have those tests, I don't think you can do much (other then biting the bullet and doing the work of rewriting the tests too). Next time try a different balance between tests and ability to change.

Fix the tests so they only test whether the requirements are fulfilled, not implementation details. If the status values are part of the specification (as is often the case with network protocols) then perhaps using them in the implementation is a good idea, but if not, it looks like you don't have TDD but DDT, design driven tests, which puts the cart in front of the horse.

How to communicate such a change is beyond the scope of this site, that's most likely a people problem.

Licensed under: CC-BY-SA with attribution
scroll top