What’s your level of code assertions?

Last year in November, Andy Hunt, of The Pragmatic Programmer and Agile Manifesto, was invited to speak exclusively to our company, and some things he said made me start thinking.

Andy seemed a bit tired and jet-lagged, to be honest, and maybe somewhat jaded from doing very similar talks about being pragmatic in your work. He did a good presentation, though, and two things he mentioned really stuck:

  • The Dreyfus model
  • Always use assertions

Let me take a moment and explain what they are.

The Dreyfus Model

The Dreyfus model covers skill acquisition and how people progress with their skill sets. The five levels are:

Novice
Needs to be told exactly what to do. Very little context to base decisions off of.
Advanced beginner
Has more context for decisions, but still needs rigid guidelines to follow.
Competent
Begins to question the reasoning behind the tasks, and can see longer term consequences.
Proficient
Still relies on rules, but able to separate what is most important.
Expert
Works mainly on intuition, except in circumstances where problems occur.

Thanks to Cory Foy for The Dreyfus Model experiment post.

Use Assertions to Prevent the Impossible

Assertions validate your assumptions. Use them to protect your code from an uncertain world.

The idea is to always use assertions to avoid any potential errors with your code, and avoid being stunned by a problem which you never ever expected to occur.

What are assertions?

Basically, it’s about making sure that things never ever go wrong. No matter how sure you (think) you are that something should never happen, or take for granted that certain dependency is available for your code, don’t. Just don’t. Call it Force Majeure, Murphy’s Law or whatever you want, but things will inevitably go wrong, sooner or later.

And when it does, that’s when quality plays in. Have you made enough and proper assertions to completely avoid it, or at least made the damage controllable?

Throughout all my professional life, in the IT business and others, people know that things go wrong. And tyeh accept it, to a certain degree. The key question is: what do you do when it does? The manner of handling problems can be the difference between a failing and successful business.

Simple examples of assertions

Let’s use JavaScript, the wonderful language that it is, to give an example:

// This is bad
document.getElementById("photo-frame").setAttribute("src", "vacation-photo.jpg");
// This is good
var photoFrame = document.getElementById("photo-frame");
if (photoFrame && photoFrame.setAttribute) { 
	document.getElementById("photo-frame").setAttribute("src", "vacation-photo.jpg");
}

The second example is good because it’s about making sure that an element exists to begin with and that it supports the method you want to call on it, before actually executing it. Assertions, people. I guess you get the drift.

This goes for all code, of course, within small as well as large scopes. And I advise you to really find out why things might not work. Try and avoid code like this:

try {
	document.getElementById("photo-frame").setAttribute("src", "vacation-photo.jpg");
}
catch (error) {
	// This should never happen
}

How do we use this?

First, let me say that I’m a firm believer in intuition. Dealing with real-life problems and situations, intuition, or gut-feeling if you will, is very often they key to doing the right choice when faced with something hard. Your whole system, be it physically or mentally, leads and guides you with all the knowledge you have ever collected, to a true decision. Or, at least what feels true at the time.

But at the same time, using assertions makes a whole lot of sense, right? I’d say that the best route to go is using a lot of assertions in your code, but at the same time use intuition as a key ingredient for any major decisions. For instance, with many JavaScript libraries out there (DOMAssistant included) a lot of the basic assertions are made for you. But don’t let yourself get lazy. It’s your responsibility to make sure any kind of assertions are in place, be it through library code or your own.

What’s your level of code assertions?

I would like to ask if you, honestly, use assertions in your code? Or maybe just some, where you know things go wrong now and then? Is this something you know you should do, but just haven’t gotten around to? Or, hopefully, are assertions so clear to you that you didn’t need to read this?

14 Comments

  • I do my very best to use assertions. Now and then I catch my self over analyzing the code I currently work on. Because of that, I usually spend more time with pen and paper before even creating the files. This helps me to at least find 8 of 10 assertions which otherwise should have breaking my creative flow.

    When it comes to javascript, Jeremy Keith's "Dom Scripting" got me interested in the first place. That book really emphasize the need of never taking anything for granted.

    IMHO, I place myself somewhere at Proficient, since I am not completely self going get.

  • I am using assertions more and more, across many technologies.

    For javscript / dom, I've been using assertions for a looong time … not wanting to throw exceptions in the face of users.

    Recently, in my day job, I've taken up FailFast (http://martinfowler.com/ieeeSoftware/failFast.pdf) and am having a great time, building more robust code, that blows up in my face early, instead of when it reaches the production environment.

    How you implement FailFast, or use assertions, I leave up to youl. But, it's certainly made my life a little easier 🙂

  • […] these aren’t the tips I’m thinking of this morning. Robert Nyman’s post on code assertions got me thinking about writing maintainable functions. I’d like to bring your attention to the […]

  • Steven Clark says:

    Another really good habit to get into when writing functions – comment above the function of the expected inputs and outputs. This can save a lot of time when the next person comes along to maintain your code.

    And meaningful names rather than variables like e, n or fp can go a long way to improving readability, and therefore maintainability.

    Sorry, maybe that was slightly off topic.

    I agree with your example in JavaScript re: try catch phrases for the purpose you've described but they have their place. I am not very strong in JavaScript though so my programming experience is not browser based.

    I've just read 2 Jeremy Keith books as I've finally picked up JavaScript and assertions seem the natural best practice. Robust quality code is an objective that should always be a priority.

  • Cory Foy says:

    Steven – why wouldn't you just write /unit tests/ to make sure those conditions are working? Even JavaScript has JSUnit.

  • Steven Clark says:

    Cory are you referring to the function inputs and outputs making it into your internal documentation (comment above the function block)?

    Your unit tests may show those conditions work. But someone scanning your code or having to make modifications will get a lot out of simply seeing what is expected as input and as output. They address a different need than unit testing.

    By writing the inputs and outputs in there you have an internal documented record of what that function takes and returns.

    I hope that explains better what I meant in my comment.

  • Robert Nyman says:

    Anders,

    Sounds like a great idea! I'm very impulsive myself, but there are times where I wish i would have sat down and thought things through properly first.

    I think very few people are experts, but I hope that I reach a level of Proficient myself within certain areas

    Morgan,

    Thanks for the tip about FailFast!

    Steven,

    Yes, good semantic names in the code is always something to strive for. And <code>try…catch</code> definitely has its place, but it usually tends to get overused.

    Steven, Cory,

    I'd say that helpful comments in the code within the right context can help other developers. However, unit tests are of course also a great way to learn.

  • Hey Robert,

    This was a great read, and a post that can be easily understood by all levels of JavaScript programmers.

    My only suggestion would be: do not begin with assertions, but be sure that your production-ready code contains assertions. The only reason I mention this, is that often I want to know when something went wrong, when it should not. Getting an "object undefined" error can be a helpful tool in debugging your scripts. However, if you do object detection from the get-go, nothing happens. The same is true with try/catch — IMHO these should be used as "I might have forgot a use-case scenario insurance policy" on a live site.

    Again, great post.

  • Robert Nyman says:

    Brian,

    Thank you!

    I agree, to a certain extent. There re certain scenarios where assertions is just a given; not having them there wouldn't be doing your job properly.

    But there's definitely other cases where you want the code to fail, to know what assertions to apply accordingly. I like to stress test my code to know when things hit the brick wall, so I can make sure it won't when being deployed live.

  • Jakob Heuser says:

    Assertions are at the core of unit testing. There's nothing quite as satisfying as writing your expected behavior, then writing the code itself.

    JS has finally reached a point where it's testing frameworks are maturing properly. http://www.jsunit.net/ is one of the more prominent ones, and I believe YUI has also fleshed out their testing framework in the most recent version.

  • I'm one of those coders that write the code until it just works regardless if it's *good* or *bad*, like a savage, sometimes (mostly) it's just horrible, and then I usually wait a while and then go back, fixing the stuff that's lazy, overly complicated, repeative or just plain wierd.

    Mostly there are no assertions in the code at this stage.

    Often I realise during the second stage, that the code I had written is nothing short of really horrible, and that it was probably just a lucky accident that it worked to begin with.

    The first go-round is like a sketch for me, I'm just looking for it to do something that I want.

    Then – after a while – I go back to the horror that is my coding, and essentially spend time doing nothing but 'saving it' back to something that's not completely offensive to the human mind.

    I've tried to change my ways, but I always fall back into this procedure nomatter what I do.

    However, this particular issue is one of those 'things' that always pop up somewhere during that second phase of rewriting.

    Thanks for posting about it.

  • Robert Nyman says:

    Jakob,

    Absolutely, JsUnit is a good advice!

    Mikael,

    Yes, I think I use the "savage" approach from time to time as well. You just want to test the concept, and eventually, in the second or third stage, the code actually gets good.

    But I guess this is one of the reason why agile development has become so popular. You want to try things out for a while, and then you're absolutely open to change your first impression, since you learned a number of things along the path.

  • […] stripped the URL in AJAX GET requests as well. Something I knew, but that’s what I get for preaching about assertions but not applying it properly to my own code. I guess my intuition took overhand for a […]

  • […] What’s your level of code assertions? […]

Leave a Reply

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