What do a warning, a comment, a test and your backlog have in common?

#warning This is going to be a nitpicky post.

There was once a developer who marked his code with TODO’s.


// TODO does not handle case X
public void Handle()
{

...
// TODO clean this up
var ugly = ...

...
// TODO re-enable after Y is implemented
// if (bla)
// {
// ...
// }

Another developer used warnings.


#warning still have to write test for this
switch (something)
{
case a: i = 4; break;
case c: i = 1;
default: throw new InvalidOperationException();

I’m writing this blog post to illustrate subtle but significant differences between four mechanisms that can be used for a shared goal: To mark what still needs to be done.

Types of to do’s

  1. “What I’m implementing now can be delivered without this change, it’s just a reminder to do this. One day. You know, sometime. When it has the highest priority.”
  2. “What I’m implementing now is not deliverable until this change is done.”

Firstly. Item 1 should not be a note in your code, it should be an item on your backlog. Your backlog item should describe what needs to be done and, if you’re concerned that a certain part in the code would be forgotten, should contain this important information. (You rarely, if every, need to point out an exact line number in your code. Your colleagues will be able to find that point in code, trust them.)

If you are making notes in your code to mark future changes that are not on your backlog, of the form “Ted, if you EVER read this, we need to…”, please think about why the work is not on the backlog and ask yourself why you are writing a comment (instead of it being added to the backlog).

If there is fear of regression in your company, the long-term solution is to address this fear by improving other parts of your code and process, not starting to write notes in your code that you know you won’t get to do unless you do it in secret (that’s kinda what a note in code is, because your project manager will rarely see them and your colleagues might not either).

Are you skipping the clean up, telling yourself you’ll do it ‘later’, because of time pressure? Wait, don’t answer that yet. I’ve found time and time again that we will assume there is time pressure that justifies delivering legacy code. Go to your project manager, explain that you need X additional hours/days to make the code production worthy. Don’t offer to skip this in that same breath! Saying “I need X more days, should I skip it?” signals that it’s a sensible option; that you’re offering that choice to him because it’s totally acceptable to leave the code in this state; that there is no difference between cleaning up and not cleaning up your code. This is not true, and you know it otherwise you wouldn’t be tempted to leave a note in your code.

If he asks, of his own accord, whether you can do it faster, reply that you can do it faster at the cost of quality. Let him make the decision and, if he decides to incur technical debt, ensure that cleaning up this technical debt is put on the backlog. Your role as a developer is to deliver high quality code, first and foremost. Set your quality targets and stick to them, until a project manager or supervisor confirms in writing that they want you to incur technical debt. I heartily recommend reading The Clean Coder by Uncle Bob. He has some strong views on the matter and although I don’t agree with his view that you should code 40 more hours a week on the side of your regular job (can be fun, but reading a book or sleeping in every now and then are also high on my weekend wish list 🙂 ), his view on the role that a developer has in the process struck a chord with me.

There are other reasons why you may be tempted to write a note in your code, instead of having it put on the backlog. Is the change so large that it cannot be done in, say, a day and needs a lot of time? (Really? Really, really?) Does it concern changes that you fear won’t get put on the backlog? Have you asked him? Be sure to discuss this with your fellow engineers and bring your concerns to the organization. Find ways to show them how much time it costs to maintain the code in the next one or two years versus investing once in this change.

Don’t write notes in code for future changes that should be on the backlog.

What I’m implementing now is not deliverable until this change is done.

Having said that, we come to the second category of notes. The breadcrumbs of coding, those virtual notes in the sideline of your code that you’re making while you’re weaving your way through many files. You know you should still add a switch case statement here, but the enum value hasn’t been added yet so you need to do that first, so bookmark* it for future reference. Writing code involves keeping the structure of the code in your mind and envisioning where your changes go. Especially given today’s open-plan offices, you may find yourself employing bookmarks of some kind in your code, because you never know when the next phone call, e-mail or colleague may appear at your desk with an interruption that will take you out of your flow.

*Speaking of bookmarks, don’t forget to use your IDE’s built-in functionality! Visual Studio offers bookmarks you can use to remind yourself of places in code you still need to visit.

warnings

Let’s get this one out of the way: A warning signals potential points of future error in your code, such as usage of deprecated methods. You should not be using warnings to write notes for yourself.

If you are using warnings to mark changes you still have to make, you probably have a different problem that is the root cause of this implicit choice. Find the root cause and solve that.

A common issue is this: If you have so many comments in code that you’re not inspecting them for TODO’s anymore and have switched to using warnings as an alternative, then I assure you your list of warnings will be assigned to the same fate in time. Nobody is cleaning up their comments, so why do you think the warning list will stay neat, clean and orderly? It won’t.

comments

Comments have the same disadvantage as warnings: If you’re not opening that Task List again and again to see if you forgot to finish up something… then you will accumulate notes of the form “Fix this in the 2001 release”. It happens.

tests

This brings me to the last mechanism of this list. I’m starting to sound like a missionary on testing, I know, but please bear with me. The advantage of using tests to identify the things you still have to do for this feature is this: Your build server will show you it’s red. You will have feedback in the form of failing tests. These tests don’t have to be perfect unit tests if your code base doesn’t support it. A test saying ‘Dude, don’t forget to call function Bla.Y from SomeClass.X() when Ted finishes the implementation’ can be as simple as the following:


// In SomeClassTests.cs
public void SomeClass_X_ShouldCallBlaY()
{
    // Arrange
    SomeClass s = new SomeClass();

    // Act
    s.X(); 

    // Assert
    Assert.Fail("TODO: SomeClass.X() should call Bla.Y()"); // Ideally, you have created and injected a mock on which you can verify expectations.
}

Heck, if that part of your code base is such a pain and instantiating SomeClass or calling s.X() can’t be done, you could even skip the instantiation and write:


// In SomeClassTests.cs
public void SomeClass_X_ShouldCallBlaY()
{
    Assert.Fail("TODO: SomeClass.X() should call Bla.Y()");
}

That way, what was originally a note in code becomes immediately visible to everyone and potentially at an earlier stage as well. The risk of a comment is that you might be the only one who knows (or forgets) that it’s there and it requires a conscious manual step to see if you forgot any. Nothing signals “something’s up” as well as a failing test.

Conclusion

There are various mechanisms you can employ to signal that there is work to be done to get the code finished and in shape. All are mechanisms that have their own time and place in the development process and have their own pros and cons. Be sure to use the right one at the right time.

Leave a Reply

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