The benefits of programming with assertions (a.k.a. assert statements)
by Philip Guo (philip@pgbovine.net)
Programming with assertions
(a.k.a. assert statements) is a great idea ...
because they provide run-time checks of assumptions that you would have otherwise put in code comments
- the run-time system knows nothing about comments
- comments often get out-of-date and out-of-sync with the code base
assertstatements (that actually end up executing) can't get out-of-date, because if they do, then they will fail for legitimate cases and you will be forced to update them
An
assertstatement simply checks a boolean condition and does nothing if it is true but terminates the program if it is false- e.g.,
assert x >= 0for making sure the input to a square root function is non-negative - e.g.,
assert isLegalSSN(joe.getSSN())for making sure that Joe's social security number (SSN) is legal due to some criteria defined by that function
- e.g.,
An assertion allows you to express in code what you assume to always be true about data at a particular point in execution ...
- ... and terminates execution as soon as your assumption is violated
- there's often no point in continuing execution if your assumptions no longer hold
You probably already write comments throughout your code to document non-obvious assumptions about the values of data structures ...
- so why don't you convert those comments into
assertstatements instead? - whenever possible, instead of (or in addition to) writing a comment,
write an
assertstatement that expresses the same details in code
- so why don't you convert those comments into
When you are writing code filled with
assertstatements, you can be more confident that when execution reaches a certain point, certain conditions are guaranteed to be met.- This can simplify your code because after the
assertstatement, you can avoid other conditional checks. e.g.,:
- This can simplify your code because after the
assert (p != null); // can now use p without first checking if it's null
When you are debugging code filled with
assertstatements, failures appear earlier and closer to the locations of the errors, which make them easier to diagnose and fix.- The longer errors propagate before causing visible trouble, the more their form can change, and the harder they are to debug.
- Have your program (at least during development) fail fast and early
- An
Assertion Erroris the best kind of error you can hope for because you have a better chance at pinpointing its source than when you receive some other random crash.
assertstatements serve as test code integrated directly into your implementation.- Whenever you execute a program containing
asserts, you are providing it with test cases. assertstatements in your implementation can complement your unit/integration testing code
- Whenever you execute a program containing
Get in the habit of writing
assertstatements for conditions that you think would be obviously true.Bugs often appear because you didn't understand all the conditions under which a piece of code can be executed, so if you think some condition must obviously be true, then it's still very possible that in some case you haven't considered, it's actually false!
If you think that at a certain point in execution,
xshould always contain less than 15 elements, then codify it in an assert- e.g.,
assert x.length < 15 - Just because you don't see any possible way that this condition can fail to hold doesn't mean that it's truly impossible
- it's very difficult for humans to reason about all possible program executions except for trivial cases
- Also, that
assertstatement serves as a concise replacement for a comment like "photo list x should always contain less than 15 photos."
- e.g.,
wah wah wah, but what about those
assertstatements slowing down my code?- in development, performance probably isn't your primary concern
- development speed and code quality trump performance!
- perhaps it doesn't even slow down your program by a noticeable
amount!
- most asserts are constant-time operations (e.g., simple boolean comparison or null check), with some more complicated ones being linear-time (e.g., membership tests for elements in list)
- if you're really paranoid, surround your
assertstatements with anifguarded by some globalDEBUGvariable that you can switch off
- in development, performance probably isn't your primary concern
but don't take my word for it, even Turing Award Winner Tony Hoare also really likes programming with assertions!
Links:
- Programming with assertions in Java
- Using assertions effectively in Python
- Related concept: Design by Contract
Last modified: 2008-06-20
