The Dark Side of Assertions
Abstract
Although the title might allude to a phrase in the newest Star Wars movie, the context of this article is more serious. First of all, it is good that people read books. However, they need to be interpreted correctly. How often aren’t design patterns misused for the fun of it? This blog article is about another aspect which made its revival with test driven design (TDD) and extreme programming (XP). This article will focus on the ‘danger’ that lies in the unmanaged use of assertions.
1 INTRODUCTION
Assertions are contracts, just as Bertrand Meyer already stated several years ago. A lot has been written already on assertions: from assertion styleguides to aspect-oriented frameworks for managing preconditions.
One of the base principles of contracts – in real life as well as in software – is the fact that it cannot be modified uni-lateraly.
For software, this implies that you cannot make your pre-conditions of your interface methods more strict all of a sudden when releasing a new version of a component.
Therefore, make sure to think upfront: The better you have thought everything through, the less contract re-negociations you will have to make in the future.
In this article, I’m using a real-life example to demonstrate the seriousness of what is – at first sight – an implementation detail.
2 A REAL-LIFE EXAMPLE
A general component which provides the implementation of a crosscutting concern is updated with extra precondition checks. Why? With the best intentions, the author of the component suddenly realised that he had forgotten to check some preconditions.
Without any further communication, the component is adapted and gets released. Of course, with the extreme programming thought in mind he also makes sure that all of his unit test work well.
Having received a new version of the software – which was just a ‘maintenance’ release by the way –, one of the applications which uses this component tries to integrate it. The integration goes seamlessly, as at first sight no ‘breaking’ changes have been made.
This is where the catch lies: In case an interface method would have been modified ‘by accident’, this would have been detected at compile-time when integrating. Integration would then be stopped prior to give an official ‘go’.
The people working on the application can run their unit tests and they – most likely – will just run. When they’re lucky the tests will fail on the extra precondition check. In a data driven environment, chances are low.
So when does this extra assertion pop up?
Of course, Murphy’s law pops up here: you can be sure of it that it will pop up at the least convenient time. As the problem can only be detected at run-time and nobody is really aware of this extra precondition it will escape the attention of both the development and QA department.
In a worst case scenario, you will see it at the customer site (when you are writing customer software), when you are giving a demo, etc. And this costs!
3 CONCLUSION
Use assertions wisely; go back to the essence of design by contract and treat every change to an assertion as a change to the contract. Secondly, make sure that your ‘contract’ is properly documented and that everybody that is involved is up to date.
REFERENCES
[Meyer88] Bertrand Meyer: “Object-Oriented Software Constructionâ€, Prentice Hall, 1988.
About the author
Mario Van Damme is a software architect, working for quite a number of years in the medical industry, and prior to that in the insurance and banking industry.
He can be contacted by e-mail at: mvandamme@sopragroup.com and mario.vandamme.mv@belgacom.net.


Assertions As Contracts, Explicit or Implicit
Thanks for this first post to your new developer.* blog, Mario. I enjoyed it, and it provided some good food for thought. One reason I have been slow to respond with a comment is that I've been thinking about your post.
I like this idea of assertions as contracts. Where things get interesting, as you point out, is when the contract needs to change, but also in the degree of explicitness in the contract. If you're working in a language like Eiffel that has explicit design-by-contract and assertion mechanisms, or if you're working with a unit testing framework that in a way serves as this documentation, then the opportunity to make this part of the contract more explicit is greater than it might be in another language, where an API reference document or JavaDoc/NDoc comment might be the only place something like that gets documented.
I remember from the many hours I spent working in Visual Basic 6 that, while it had a certain power in a lot of other areas, one of the areas it was lacking was language-level support for assertions. There was an Assert() method on the intrinsic Debug object, but that only worked while physically running the program in the interactive debugger (that is, you could not do a deployable debug build with the assertions enabled). That said, I still implemented my own assumption validation and input checking code in any kind of component methods or property setters I coded.
I wonder if the lack of consistency of idea or implementation across languages and tools for assertions, preconditions, and the like has contributed to a lack of knowledge or momentum for this technique. Outside of certain language or methodology communities where contracts and/or assertions are part of the modus operandi, I would posit that these concepts are either non-existent or little used.
What I mean is, they are not being used consciously, in a systematic and explicit way. For example, someone could argue that an interface in any object oriented language represents a contract, but that does not mean the program designer and/or maintainer is thinking of them that way. As another example, .NET has assertion mechanisms, but I don't hear much about people using them--and I've never encountered them in anyone else's code. (While doing a quick search just now, I found this very nice explanation /critique of .NET assertions.)
Another idea that seems useful is that the patterns and conventions inherent in your implicit contract (the assertions and preconditions) should align with the patterns and conventions of the explicit contract. I would say this is true regardless of whether the language being used offers an explicit mechanism for contracts and/or assertions, as Dr. Meyer's Eiffel language does. The idea is that a person should to some degree be able to guess what the assertions would be based on your patterns.
I've not had the pleasure of reading the classic Bertrand Meyer book you reference. That's probably something I should remedy.
Thanks again, Mario.
Welcome.
Dan
P.S.
Mario and I have been going through the editing process for an article written by Mario that will appear in developer.* in the near future. The article is about best practices and strategies for O/R mapping layers and persistency APIs [note added later: here is the article]. Mario lives in Belgium, land of the best beer in the world. I'm sure there are many other great things to say about Belgium, but I've never had the pleasure of a visit, and the wonderful beer--and chocolate--is my only frame of reference. MMmmmmmmm....Westvleteren...