Categories
Development

You should write more unit tests

I write a lot of unit tests. There have been some days when I spend more than half the day just writing tests. I haven’t fully adopted test-driven development, but I know the value of unit tests and want to make sure my code is covered. There have been times in the past when I haven’t written as many tests, and when I finally do take the time to cover that code with tests, I inevitably find some problem with it. Writing tests not only helps me clarify the process of doing something in my code, but it makes my code more easily extensible and testable.

We’ve hired a few new developers where I work, and they always react with astonishment when I tell them how many tests I have and how much code is covered by those tests. This is a bit upsetting. They’re writing tests, but most of what they write are integration tests: tests that make sure the various bits work together. They don’t have many tests that simply make sure some small piece of code is doing what it should. Their integration tests are good to have (I’m not arguing against integration testing), but unit tests are quick to run and provide a safety net to maintain a healthy codebase and track down bugs when they happen.

To illustrate my point, let’s take some pseudo-code for a real-life example:

public bool CanEdit
{
    get { return this.CanPerform(AuthorizationAction.Edit); }
}

This is a simple C# property that returns a value indicating if I can edit the class it’s attached to. The server tells me what I’m allowed to do, and I’m simply exposing that through this property. A unit test might look something like this:

public void CanEditTest
{
    var obj = new Thing();
    obj.Authorizations.Add(AuthorizationAction.Edit);

    Assert.IsTrue(obj.CanEdit);
}

This all looks pretty basic, and you’d be right: it’s about as simple as things can get. One might ask, “That code is very simple and straightforward. Why do I need to write a test for it?” Well, consider that I write a lot of these authorization properties and they all follow the same structure, so I do a lot of copy/pasting and rename them. Occasionally, I’ll forget to change the action I’m checking for in the “CanPerform” part. This test makes sure I don’t forget, and since this test runs every time I check-in code, it makes sure I never accidentally break it.

A coworker once told me, “it looks like you’re making sure you don’t change anything.” I was a little surprised. Of course I’m making sure I don’t change things, I thought, I know it works. I don’t want to change it. Refactoring is fine, and wouldn’t break the test. But if we completely change something – say we completely change how authorization works – these tests should fail. You’ve changed how something works, of course you’ll need to update the tests.

Part of the problem is that most developers seem to think of unit testing as extra work, but that’s not the case. It’s a developer’s responsibility to make sure they code they write works. If you’re not writing tests for it, you can’t be confident that it actually works. You can’t be confident that someone else will make a change that breaks it. And you can’t rely on a QA tester to catch everything you missed. Be a good developer: write unit tests.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.