Search This Blog


Thursday, February 14, 2008

Unit Testing, What a Pain! (2)

My post on my painful experience with unit testing drew quite a number of responses. There are points that I wish to respond here:
paulo said...

You're doing it wrong. If there is high coupling, unit testing helps you recognize it and is an incentive to fix it. If setup is complicated, it means you're not using factory classes that could simplify your main code immensely. If you're bitching about dialog boxes, you're probably unit testing at the wrong level of the software. I don't really know anything but this should be obvious

paulo got a point here. But the problem of testing the untestable code is that there is no way to detect high coupling, poor separation of concern and other design smells before you write test on it. And since untestable code wasn't written with unit test, there is no way to fix the design smells at all.
I know writing untestable code is bad. But I only knew it when I was exposed to unit testing and TDD. I didn't know it when I started my career as a programmer. And that's the problem, those code was functioning code, I can't fix them without breaking them.

There was no way to create unit test for legacy code, as far as that project was concerned.

So I threw away the old codebase and started with a new one. I couldn't work with the old codebase anymore.

One commenter didn't like to write unit tests on legacy application:
Yeah, I agree. I wouldn't even attempt to do unit testing on an existing application. And I wouldn't do anything but test driven development if the goal was to have unit tests.

Unit/integration/etc testing is a development style, not something you tack on later. It influences everything about how you design your code. When doing TDD, all your code is testable, because it has to be. You simply write applications differently.

Maybe for some projects, not being able to create unit test is not so much of a problem. Maybe for those projects, you can easily or economically start from scratch and rewrite the whole thing without much impact to the underlying business. Or maybe once the application is released, there is little point in maintaining it.

But there are a lot of real life projects that can't suffer a rewrite or require ongoing maintenance. Since they don't have Upfront Unit Test, the maintainer needs to create unit tests during maintenance stage or automated regression tests. Under this situation it is not excusable to say that you can't work with those legacy code or you can't create any unit tests at all.

The boss is paying you to clean the mess and you can't simply walk away just because the code is badly written. You have to find ways to solve the problem. Of course things could have been better were the previous programmers wrote the programs in TDD fashion, but if they didn't, it's your problem, not theirs. You can curse or moan or cry, but the crap is still yours.

Sad, isn't it? But this is life.


Nat Pryce said...

If the code has no tests and is poorly designed, unit testing is the wrong granularity of tests to start with. First get the system covered by end to end tests. Then identify the areas of the code you want to modify and cover those with finer grained integration tests. When the coverage is high enough, you can address the design issues and introduce unit tests as you refactor to clearly delineated units.

Soon Hui said...

Nat, good idea. That was what we did with our legacy applications as well.