Should we unit test trivial code?
A dilemma that I’ve had long time ago: should I unit test a very trivial code, with a very trivial unit test?
Answer: yes.
I remember that once I had a class which, in that moment, had only a getter and a setter. Something like:
class Contacts
{
public:
void setContacts(int contacts) { m_contacts = contacts; };
int contacts() const { return m_contacts; };
private:
int m_contacts;
};
Unit test or not unit test? That was the question…
I think that, when I wrote it, I thought not to unit test.
Weeks later someone asked me how some other part of the software would behave if the user had 5 contacts. To do a quick test I did:
int contacts() const { return 5; };
Sadly, this temporary change got committed to the repository! (“git commit -a” is sometimes not your friend).
So, one reason to unit test this trivial code: avoids an error like it happened. Someone could say that a code review should have detected it, but we weren’t doing code reviews at that time. Someone else could say that I should use QObject properties to avoid problems implementing a trivial case – but I’m sure that in some case this needs to be implemented without a QObject.
Another reason to test a class like this (not the getter/setter): the next person who will change the class will have a unit test skeleton for this class. I can see how someone adds a trivial change to the class and thinks “well, it doesn’t have any unit test, so I’ll not add one for this small change”. And after many small trivial changes perhaps the class is not so trivial anymore. Or by adding the trivial change something else gets broken. At the end, the class is so trivial with a trivial change that maybe we don’t pay much attention to (the original coder, reviewer, etc.).
We discussed about some similar questions in the talk of Bo Thorsen, from Fioniasoftware in the 2012 Qt Developers days. He discussed a bit about this topic there. Sadly I didn’t discuss about this case, trivial code with a trivial test.
The discussion in the conference was “should we aim to have a test coverage of 100%”? The question sounds similar to the above case, but it’s not: there are other cases where some code is very hard to test (especially GUI code).
I have to say that sometimes I need to remember this problem when I’m writing a trivial unit test for a trivial code, seems that I want to fool myself.
I don’t like to test, it takes a lot of time, specially in a one-person-project.
I found more interesting and useful to review the code once it’s in GIT (color-diff), because there I see some TODO comments that I haven’t deleted and other kind of stuff like the “return 5” you pointed.
One difference between an experienced developer and a novice is that the experienced does all the checks before writing a file (to see if it’s writeable, space on disk, …) and does tests before starting a thread,…
In my opinion this tests are important, but the unit testing of trivial code is a lost of time and it’s a work that it’s partially done by users.
Of course this is only the opinion of someone more interested in features than in robustness. If I was working in a critical project then maybe I will say the opposite, but it wouldn’t be a one-person-project (I hope).
Cheers!
Test or not test: it depends of the cost of the bug when it’s released to the users.
At Mendeley can be quite “expensive”: users complains, time in support, time with the engineers to detect the bug, perhaps it needs a new release, some days with some users experiencing the bug, bad image…
If it’s a weekend script the cost of the bug is cheaper.
Sometimes some unit tests helps to build something. I’ve just arrived from another Python Code Dojo, we have done a Roman Numeral calculator and it’s a case where test driven development is quite useful and practical! (write that I + I is II, III + II is V, etc. etc. and then start implement. Helps catching regressions, for example).