Don't Underestimate the Benefits of "Trivial" Unit Tests

Take a look at the following example of a trivial unit test for a property. Imagine a class MyClass with a property Description:

public class MyClass
{
...
private string m_strDescription;
public string Description
{
get { return m_strDescription; }
set { m_strDescription=value; }
}
...
}

And here's the accompanying unit test:

    ...
[ Test ]
public void DescriptionTest()
{
MyClass obj=new MyClass();
obj.Description="Hello World";
Assert.AreEqual("Hello World", obj.Description);
}
...

Question: What's the benefit of such a trivial test? Is it actually worth the time spent for writing it?

As I have learned over and over again in the past months, the answer is YES. First of all, knowing that the property is working correctly is better than being "really, really sure". There may not be a huge difference in the moment you write the code, but think again a couple weeks and dozens or hundreds of classes later. Maybe you change the way the property value is stored, e.g. something like this:

 

    public string Description
{
get { return m_objDataStorage.Items["Description"]; }
set { m_objDataStorage.Items["Description"]=value; }
}

Without the unit test, you would test the new implementation once, then forget about it. Now another couple of weeks later some minor change in the storage code breaks this implementation (causing the getter to return a wrong value). If the class and its property is buried under layers and layers of code, you can spend a lot of time searching for this bug. With a unit test, the test simply fails, giving you a pretty good idea of what's wrong.

 

Of course, this is just the success story... don't forget about the many, many properties that stay exactly the way they were written. The tests for these may give the warm, fuzzy feeling of doing the "right thing", but from a sceptic's point of view, they are a waste of time. One could try to save time by not writing a test until a property's code is more complicated than a simple access to a private member variable, but ask yourself how likely it is that this test will be written if either a) you are under pressure, or b) somebody else changes the code (did I just hear someone say "yeah, right"? ;-). My advice is to stop worrying about wasted time and to simply think in terms of statistics. One really nasty bug found easily can save enough time to write a lot of "unnecessary" tests.

 

As already mentioned, my personal experience with "trivial" unit tests for properties has been pretty good. Besides the obvious benefits when refactoring, every couple of weeks a completely unexpected bug gets caught (typos and copy/paste- or search/replace mistakes that somehow get past the compiler).

4 Comments

  • I'm not intending to disagree, since I do really agree its better to have something over nothing, but I did want to point out a subtle possible "flaw" here -- one that I've seen. What happens when you change the storage mechanism to something shared across instances, or maybe have the class itself shared in some sense, both of which happen all the time in web scenarios, and maybe others? The subtle "flaw" is that the unit test can still pass with green lights in the single user test case developers typically test, but it may actually still fail in the real world! Again, this isn't to say that the unit test has no value, for I agree it still does, but you must still be careful in such cases to not assume a passing test always means its OK.

  • I don't know who said it or where I read it: "Unit tests are a tool for showing the presence of features, not for showing the absence of bugs" ;-)

    So definitely agree with you.

  • I tend to stay away from unit-testing property accessors.



    The issue that you describe (about the new implementation in the storage code) should be discovered by unit tests on the storage code.



    If you are using continuous integration in conjunction with a comprehensive set of unit tests, then you can verify that all code works immediately upon checkin.

  • > The issue that you describe [...] should be discovered by unit tests on the storage code.

    Yes, you are right.



    Maybe my positive experiences are based on working in what could be described as a "mixed environment moving towards full TDD", where the desired test coverage has not been achieved yet.



    I will keep writing these trivial tests (along with the "real" tests, of course) and will watch how the rate of detected mistakes/bugs develops in the next months. Let's see what the results are.

Comments have been disabled for this content.