Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

So today I had a talk with my teammate about unit testing. The whole thing started when he asked me "hey, where are the tests for that class, I see only one?". The whole class was a manager (or a service if you prefer to call it like that) and almost all the methods were simply delegating stuff to a DAO so it was similar to:

SomeClass getSomething(parameters) {
    return myDao.findSomethingBySomething(parameters);
}

A kind of boilerplate with no logic (or at least I do not consider such simple delegation as logic) but a useful boilerplate in most cases (layer separation etc.). And we had a rather lengthy discussion whether or not I should unit test it (I think that it is worth mentioning that I did fully unit test the DAO). His main arguments being that it was not TDD (obviously) and that someone might want to see the test to check what this method does (I do not know how it could be more obvious) or that in the future someone might want to change the implementation and add new (or more like "any") logic to it (in which case I guess someone should simply test that logic).

This made me think, though. Should we strive for the highest test coverage %? Or is it simply an art for art's sake then? I simply do not see any reason behind testing things like:

  • getters and setters (unless they actually have some logic in them)
  • "boilerplate" code

Obviously a test for such a method (with mocks) would take me less than a minute but I guess that is still time wasted and a millisecond longer for every CI.

Are there any rational/not "flammable" reasons to why one should test every single (or as many as he can) line of code?

share|improve this question

6 Answers

up vote 21 down vote accepted

I go by Kent Beck's rule of thumb:

Test everything that could possibly break.

Of course, that is subjective to some extent. To me, trivial getters/setters and one-liners like yours above usually aren't worth it. But then again, I spend most of my time writing unit tests for legacy code, only dreaming about a nice greenfield TDD project... On such projects, the rules are different. With legacy code, the main aim is to cover as much ground with as little effort as possible, so unit tests tend to be higher level and more complex, more like integration tests if one is pedantic about terminology. And when you are struggling to get overall code coverage up from 0%, or just managed to bump it over 25%, unit testing getters and setters is the least of your worries.

OTOH in a greenfield TDD project, it may be more matter-of-fact to write tests even for such methods. Especially as you have already written the test before you get the chance of starting to wonder "is this one line worth a dedicated test?". And at least these tests are trivial to write and fast to run, so it's not a big deal either way.

share|improve this answer
Ah I totally forgot that quote! Guess I will use it as my main argument because frankly - what can break here? Not really much. Only thing that can break is the method invocation and if that happens than it means something really bad happened. Thanks! – Zenzen Jan 19 '12 at 21:35
@Zenzen: "what can break here? Not really much." - So it can break. Just a small typo. Or somebody adds some code. Or messes up the dependency. I really think that Beck would claim that your main example qualifies as breakable. Getters and setters, less so, although I have caught myself out in a copy/paste error, even then. The real question is, if it's too trivial to write a test, why does it even exist? – pdr Jan 19 '12 at 21:44
1) I would not test the dependency because it would be an integration test. I would use a mock. 2a) if somebody adds some code then he adds actual logic WHICH should be tested then. 2b) Setters don't qualify then? Why? What if someone adds some code to them? Same thing. 3) Why is it there? Just to adhere to the common layered architecture of the application. Following that logic everything can break ;) – Zenzen Jan 19 '12 at 21:48
The amount of time you spent thinking about it already you could have written the test. i say write the test, don't leave when not to write a test as a grey area, more broken windows will appear. – kett_chup Jan 20 '12 at 0:11
Assuming that EITHER you're looking at mocking out your DAO when you unit test this class OR you have separate tests for your DAO methods; don't bother testing the one-line methods that call the DAO. It doesn't make economic sense to spend a finite amount of time on a test that has a zero chance of finding any bugs. – David Wallace Jan 20 '12 at 3:22
show 1 more comment

Here's good way to think about quality of your software:

  1. type checking is handling part of the problem.
  2. testing will handle the rest

For boilerplate and trivial functions, you can rely on type checking doing it's job, and for the rest, you do need test cases.

share|improve this answer

In my opinion cyclomatic complexity is a parameter. If a method is not complex enough (like getters and setters). No unit testing is needed. McCabe's Cyclomatic Complexity level should be more than 1. Another word there should be minimum 1 block statement.

share|improve this answer
Remember some getters or setters have side effects (although it is discouraged and considered bad practice in most cases), so change in your source code may also affect it. – Andrzej Bobak Oct 20 '12 at 21:41

It's a tricky question.

     Strictly speaking I would say that it is not necessary. You are better off writing BDD style unit and system level tests that insure business requirements function as intended in positive and negative scenarios.

     That said if your method is not covered by these test cases then you have to question why it exists in the first place and if it is needed, or if there are hidden requirements in the code that are not reflected in your documentation or user stories which should be encoded in a BDD style test case.

     Personally I like to keep coverage by line at around 85-95% and gate check-ins to mainline to insure existing unit test coverage per line hits this level for all code files and that no files are uncovered.

  Assuming best testing practices are being followed this gives plenty of coverage without forcing developers to waste time trying to figure out how to get additional coverage on hard to exercise code or trivial code simply for the sake of coverage.

share|improve this answer

Your answer on this depends on your philosophy (believe it is Chicago vs London? I'm sure someone will look it up). The jury is still out on this on the most time-effective approach (because, after all that's biggest driver of this- less time spent on fixes).

Some approaches say test only the public interface, others say test the order of each function call in every function. Plenty of holy wars have been fought. My advice is to try both approaches. Pick a unit of code and do it like X, and another like Y. After a few months of test and integration go back and see which one fit your needs better.

share|improve this answer

This made me think, though. Should we strive for the highest test coverage %?

Yes, ideally 100%, but some things are not unit testable.

getters and setters (unless they actually have some logic in them)

Getters/Setters are stupid - just don't use them. Instead, put your member variable to public section.

"boilerplate" code

Get common code out, and unit test it. That should be as simple as that.

Are there any rational/not "flammable" reasons to why one should test every single (or as many as he can) line of code?

By not doing so, you might miss some very obvious bugs. Unit tests are like a safe net to catch certain kind of bugs, and you should use it as much as possible.

And the last thing : I am on a project where people didn't want to waste their time writing unit tests for some "simple code", but later they decided not to write at all. At the end, parts of the code turned into big ball of mud.

share|improve this answer
Well lets get one thing straight: I didn't mean I do not use TDD/write tests. Quite the opposite. I know that tests might find bug that I didn't think about, but what is there to test here? I just simply think that such method is one of the "not unit testable" ones. As Péter Török said (quoting Kent Beck) you should test stuff that can break. What could possibly break here? Not really much (there is only a simple delegation in this method). I CAN write a unit test but it will simply have a mock of the DAO and an assert, not much testing. As for getters/setters some frameworks require them. – Zenzen Jan 19 '12 at 21:28
Also, since I didn't notice it "Get common code out, and unit test it. That should be as simple as that.". What do you mean by that? It is a service class (in a service layer between the GUI and the DAO), it is common to the whole app. Can't really make it more generic (since it accepts some parameters and calls a certain method in the DAO). The only reason it is there is to adhere to the layered architecture of the application so the GUI won't call the DAO directly. – Zenzen Jan 19 '12 at 21:33
12  
-1 for "Getters/Setters are stupid - just don't use them. Instead, put your member variable to public section." - Very wrong. This has been discussed several times on SO. Using public fields everywhere is actually worse even than using getters and setters everywhere. – Péter Török Jan 19 '12 at 21:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.