Tuesday, November 13, 2007

Trivial Pursuit: Unit-Testing Getters and Setters

While I was in Vegas, Eric, Alex, and Brian posted some ideas on unit testing trivial code.

The question: should we unit-test everything? The hive-mind currently says: yes.

E.g. Relevance recently posted a job offer that mentions 100% code coverage. At a recent NFJS, Stuart Halloway made the point that code coverage is one of the few things where one has to be extreme: 80% doesn't work; it has to be 100%. (Relevance is adamant on this point.)

Fine, so the answer is yes. But how do we remove the tedium of writing that testing code?

  • Modern IDEs generate code for getters/setters. They should do the same thing for generating unit-tests for this code. I haven't seen this: perhaps they already do? I've looked in Idea 6 and didn't see anything obvious.
  • It seems possible to write an abstract base class for unit-tests that uses reflection to auto-test common getters/setters. Is there such a tool out there?
  • Interestingly, we are seeing the impact of this issue in language development. Groovy will auto-generate getters and setters for a class member if they aren't provided. Not only is there less code to read, but also there is less code to test.
Post a comment if you know of a neat method to facilitate this testing...

ps. Here is a post from last winter on my experiences with unit-testing: in particular, TDD. It was a true growth experience for me.

pps. Here is the obligatory acknowledgement that getters/setters should not be automatically provided without just cause!

8 comments:

Unknown said...

Mario left a very insightful comment on my blog. You can still achieve high coverage WITHOUT directly testing the getters and setters for trivial classes. The key is to test the more complex classes, which ends up exercising the trivial code indirectly, thus you still get good coverage.

Tony said...

It was good to read this entry as I've come to the conclusion also that you gotta test your setters and getters. (http://homepage.mac.com/hey.you/lessons.html)

Where this works well for me now is in conjunction with clover. Since my bar is green on all but 2 or so classes per project, when a new bit of code doesn't fully get 100% coverage, it really jumps out at me because of the red clover bar.

I'd also add that we have getters and setters theoretically because we want to hide the implementation, we might change the internal representation to something else. If that is the case, why wouldn't you test a simple setter /getter.

Anyway, my experience is the extra value you gain from having 100% and the green clover goodness is worth the small amount of pain you get from testing setters and getters.

Tony said...

Link to my lessons article didn't come through, try this

http://homepage.mac.com/hey.you

Anonymous said...

Tony: Writing unit tests for simple getters/setters so that Clover gives you 100% coverage certification is, IMO, an inversion of priorities.

The developer's job is to complete the project writing correct, clean, maintainable code. Doing things like unit testing getters/setters, which does not advance this goal is just lost time and effort. More so when the motivation is purely to satisfy the yearning for graphical gratification.

Honestly, someone on my team doing this would definitely be spoken with.

If you're doing something that advances the project, you're not helping.

redsolo said...

For C# there a util class that will let you test getters and setters/properties. I have been trying to find such a class for Java but havent found any, but there must be one as it is not really rocket science.

Anyhow you can find the stuff at http://www.thejoyofcode.com/Automatically_Unit_Test_your_Model.aspx

redsolo said...

Link, again,
http://shorl.com/taprukunapadu

Tony said...

If your getters / setters weren't working, wouldn't you want to know about it?

One of the ways that 100% code coverage really helps a project is you quickly pick out those classes that are not tested fully. The difference between 87% coverage and 88% coverage doesn't show up as much of a difference.

But, the difference betweeen 99% and 100% shows up as a huge difference when you use tools like Clover.

Sure, testing setters/getters can seem trivial but the advantage of having all packages and classes at 100% is great because you instantly see where you have missed tests. That single advantage makes the trivia of testing setters/getters well worth it in my opinion.

Once you cannot see a singular missing test, it is a slippery slope to being unable to see multitudes of missing tests.

It may be this isn't an issue on a small project but on the larger projects I've been involved with the missing test visibility advantage gained by testing setters was well worth the effort.

Anonymous said...

The only "good" code coverage is 100% code coverage. The only method not worth testing is the one that will never be invoked, and which, consequently, should be removed.

anonymous: How, exactly, do you ascertain the "correctness" of code, without testing it? If I understand correctly, your developers have learned to avoid getting 100% code coverage, lest they otherwise find themselves being "spoken with."

Testing all getters/setters is the cheapest, easiest way to ensure that when Clover indicates 2% of your code isn't being covered, that 2% won't be written off and ignored -- it WILL be significant code.