03/20/05: Feature Envy and Self-Testing Code

I've been toying with IDEA's Feature Envy warning lately. It highlights methods that repeatedly refer to another object -- the heuristic here is that if a method M in object A makes heavy use of object B, then maybe M should be on object B instead. This captures a general OO concept that I've been advocating for a while but never had a good name for (or, more likely, forgot the name of after I read Refactoring by Martin Fowler). If nothing else it simplifies your code by replacing an explicit parameter with the implied this pointer.

There's one flaw: any good unit test method is going to set off this alarm, which makes it kind of annoying. You can disable it on a per-method basis (with a JavaDoc comment -- ugh) but I thought it might be nice to turn it off on all JUnit classes, or on all code in your IDEA-marked test source directories. But then I had another idea.

What about a testing framework that not only looked for all classes named Test, but all classes in your entire codebase containing public methods starting with the word "test"? This harks back to the pre-JUnit days of self-testing objects with a main method. These self-test methods wouldn't have to use the hack of package protection to test class-private stuff, and have the advantage that they never get lost, and that you don't need any naming conventions to find the unit tests for any given object.

One downside would be that your production code would become a bit bloated with test code, but unless I'm building an applet I don't care about that at all these days. Another problem is that it doesn't allow for multiple setup/teardown scenarios, but that's easily overcome either by using custom test fixtures, or by resorting to the traditional external test class.

It would actually be pretty easy to write a JUnit suite like the one Erik Hanson wrote that makes a little proxy Test object for each self-testing class... Hmm...

Comments made

The applet problem can be solved with an obfuscater like ProGuard.

I'm not sure putting test code in with the stuff it is testing would be a step forward for readability (especially if various test stuff crept out of the test methods and into fields, inner classes, helper methods, etc).

But you are right that it takes care of the private issue.
03/21/05 00:52:31

Add comment

Sorry, but due to blog comment spam, I have to ask you to create an account before you post a comment. Please log in (using the form on the top right of the page) or click here to create an account: Create an account!