Unit-testing – Is it a good idea to write all possible test cases after transforming the team to TDD to achieve a full coverage

acceptance-testingbddtddtestingunit testing

Assume we have a large enterprise-level application without any unit/functional tests. There was no test-driven development process during the development due to very tight deadlines (I know we should never promise any tight deadlines when we are not sure, but what's done is done!)

Now that all deadlines passed and things are calm, everyone agreed to transform us into a productive TDD/BDD based team…Yay!

Now the question is about the code that we already have: (1) Is it still okay or good idea to stop most of the development and start writing whole possible test cases from the beginning, even though everything is working completely OKAY (yet!)? Or (2) it's better to wait for something bad happen and then during the fix write new unit tests, or (3) even forget about previous codes and just write unit tests for the new codes only and postpone everything to the next major refactor.

There are a few good and related articles such as this one. I'm still not sure if it worth to invest on this considering we have a very limited time and many other projects/works are waiting for us.

Note: This question is explaining/imagining a totally awkward situation in a development team. This is not about me or any of my colleagues; it's just an imaginary situation. You may think this should never happen or the development manager is responsible for such a mess! But anyway, what's done is done. If possible, please do not downvote just because you think this should never happen.

Best Answer

There was no test-driven development process during the development due to very tight deadlines

This statement is very concerning. Not because it means you developed without TDD or because you aren't testing everything. This is concerning, because it shows you think TDD will slow you down and make you miss a deadline.

As long as you see it this way you aren't ready for TDD. TDD isn't something you can gradually ease into. You either know how to do it or you don't. If you try doing it halfway you're going to make it and yourself look bad.

TDD is something you should first practice at home. Learn to do it, because it helps you code now. Not because someone told you to do it. Not because it will help when you make changes later. When it becomes something you do because you're in a hurry then you're ready to do it professionally.

TDD is something you can do in any shop. You don't even have to turn in your test code. You can keep it to yourself if the others disdain tests. When you do it right, the tests speed your development even if no one else runs them.

On the other hand if others love and run your tests you should still keep in mind that even in a TDD shop it's not your job to check in tests. It's to create proven working production code. If it happens to be testable, neat.

If you think management has to believe in TDD or that your fellow coders have to support your tests then you're ignoring the best thing TDD does for you. It quickly shows you the difference between what you think your code does and what it actually does.

If you can't see how that, on its own, can help you meet a deadline faster then you're not ready for TDD at work. You need to practice at home.

That said, it's nice when the team can use your tests to help them read your production code and when management will buy spiffy new TDD tools.

Is it a good idea to write all possible test cases after transforming the team to TDD?

Regardless of what the team is doing it's not always a good idea to write all possible test cases. Write the most useful test cases. 100% code coverage comes at a cost. Don't ignore the law of diminishing returns just because making a judgement call is hard.

Save your testing energy for the interesting business logic. The stuff that makes decisions and enforces policy. Test the heck out of that. Boring obvious easy-to-read structural glue code that just wires stuff together doesn't need testing nearly as badly.

(1) Is it still okay or good idea to stop most of the development and start writing whole possible test cases from the beginning, even though everything is working completely OKAY (yet!)? Or

No. This is "let's do a complete rewrite" thinking. This destroys hard won knowledge. Do not ask management for time to write tests. Just write tests. Once you know what you’re doing, tests won't slow you down.

(2) it's better to wait for something bad happen and then during the fix write new unit tests, or

(3) even forget about previous codes and just write unit tests for the new codes only and postpone everything to the next major refactor.

I'll answer 2 and 3 the same way. When you change the code, for any reason, it's really nice if you can slip in a test. If the code is legacy it doesn't currently welcome a test. Which means it's hard to test it before changing it. Well, since you're changing it anyway you can change it into something testable and test it.

That's the nuclear option. It's risky. You're making changes without tests. There are some creative tricks to put legacy code under test before you change it. You look for what are called seams that allow you change the behavior of your code without changing the code. You change configuration files, build files, whatever it takes.

Michael Feathers gave us a book about this: Working Effectively with Legacy Code. Give it a read, and you'll see that you don't have to burn down everything old to make something new.