The Ugly Testling


What do you do when your trying to be agile but your application pulls you towards rigid? Let’s say you have some existing code that you need to change. By existing code I mean the kind of code that exists merely because its code. Code that’s 99% programmed for its own inconsistencies and adds 1% value. Ugly AT&T code that reaches out to touch everything. You can’t just take the object in question and run in a unit test because it imports several other objects to do its job. Each of these other objects are potentially as ugly as the code that needs changing. Testing in isolation is out of the question. You can’t touch the code because Mr. Agile, your shoulder angel, is begging you to “please write a test first!” Mr. Management, your shoulder demon, coerces you to “just slam something in there, build deploy and eyeball the result!” What do you do?

Enter the Ugly Testling

The ugly testling is something I’ve used in a pinch to make me feel agile as I work on legacy prexisting code. You’re stuck testing some object in place which means you need to involve a rather large part of your application. Often it involves unrelated difficult to test things such as EJB remoting protocols, databases, and or the file system. You need to build walls around the piece of code you want to test which means you need to either emulate or load large portions of your app. Depending on how ugly the code is you may get away with Mock Objects for the vast majority of these pieces. I won’t go into detail on how to write one of these ugly testlings. You just grit your teeth, close your eyes, and and do what you have to with the available APIs. My point here is what do you do with the testling? He doesn’t look like the other unit tests so he feels all alone… neglected! You feel bad because how could you give birth to such a bastard child? How can you Neglect your own creation? You disgraceful parent!

The problem is the testling thiks he’s a unit test like all of his brothers and sisters but he’s not. He’s big and bloated. He often lives in a different home, “tests-functional”, instead of “tests”. The other tests won’t play with him because he takes too long to execute. You won’t give him any attention because he involves too many specifics about his environment. He just sits alone and wonders, “will he ever grow up to be a swan… err unit test?”

I’ll spare you the ending of my little fairy tail because it’s not a happy ending. Truth be told, I kill many of my ugly testlings because I’m a murderer! I’m a crazy blood thirsty inconsiderate test killer! After they validate the code and allow me to sneak a quick and dirty change in then they’ve outlived their usefulness. I’m ratting myself out because you really shouldn’t use these testlings for quick and dirty fixes. That kind’a defeats the purpose. It becomes difficult because after putting such effort into birthing an ugly testling (they are sometimes delivered via C-section) there’s little time left to complete your code change. So then I’m in the middle of a two way argument between my shoulder angel and demon.

Angel: Just a little more effort and you’ll have the whole thing refactored the right way!”

Demon: C’mon! Look at this mess! A little refactoring only fixes part of the problem. You still have to deal with integration issues.

Angel: What you’re sitting on is an integration test. What better way to deal with integration issues!

Demon: Yo’ momma!

Angel: My momma??!! Yo’ bald-headed granny!

Demon: Yo’ momma’s so fat when she stepped on the scale she saw her social security number!

I tune them both out at that point. If you think making that decision is tough, explaining to your coworker who happens by while you’re twisting your head left and right watching two invisble midgets play the dozens is even tougher. I’m still left with lots of questions each day. What do you do with ugly code? What do you do with the ugly testling to test the ugly code? Why doesn’t Donald Trump ever change his hair style? Throw some knowledge on me…

(With the keen understanding that knowledge can neither be thrown or even grabbed in any physical form the idea is that you leave a comment while brushing up on your street slang.)

3 thoughts on “The Ugly Testling

  1. Have you ever read “Oh no, we’re testing the mock!”? ( http://blogs.codehaus.org/people/rinkrank/archives/000551_oh_no_were_testing_the_mock.html )

    Ugly, untested code should live on untested. You just hope it works. Mock it mercilessly! Make sure your app calls the right methods.

    Sometimes, I write an interface that I can use with the mock, and an adapter that calls the ugly monster and implements the interface. Of course, this can lead to an untested adapter: make sure the adapter’s methods call one or two methods from the ugly at most. They are allowed to map arguments, though:

    public void sendMessage(UglyHeader header, UglyContent content) {
    ugly.sendMessage(header, new UglyComponents[]{header, content});
    }

    Sad to see how slowly ugliness gets purged…

  2. Tiago,

    Yes I’ve read that before. Very good topic indeed. Mocking only goes so far. Even JMock with CGLib fails to mock static methods on a class and final classes. I find myself frequently in a situation where my tests are highly coupled with my implementation logic and/or test such a huge part of the app that they’re more of an app test than a unit test. The best thing to do I feel is to refactor carefully after getting one of these ugly testlings in place. Carefully because such a cumbersome test can barely capture all of the potential code paths that exist so you are open to introducing bugs even with a test in place. Sadly it is a shame to see such ugliness…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s