Contents

Do not comment. Assert it!

Today I have discovered lots of things about this great unknown assert.

It happens that I had a very strong debugging tool too close from myself and I hadn’t used it.

Trying to fix this problem, I write this article, but I am not going to write anything that is not already written at Java Assert Documentation or Python Documentation.

Test

The more basic

First step is to know how to use it. You can use it in two ways: with one or two parameters. The second one will be a text to be shown with the exception when the first one do not match.

Using python:

1
2
assert expression
assert expression1, expression2

And using Java:

1
2
assert expression;
assert expression1 : expression2;

It is important to highlight that, if expression1 is not evaluated as true, second one will not be executed. usually, this second expression must return a string.

Do not use Assert!!

You are not going to use a pneumatic hammer to tighten a screw, so you cannot use assert everywhere.

You must not use it in next cases:

  • Public Methods: This is an aesthetic point, because it would be horrible to find an “Assertion Error”. It is better to find a “Some error happened”, so it is better to use a comparation and an exception. In addition, you can disable asserts, so you can break off checking the public method input.
  • To do useful stuff inside a method, because asserts can be disabled and it would break off doing that job.

Use Assert!!

Usually, we tend to write comments like “Everything OK”, “It must not get here”, etc. This kind of comments is a problem because they can become lies and, in the other hand, nobody is checking them.

In addition, you need too much letters to say the same (comment compared with the equivalent assert):

1
2
# value must be greater than five
assert i > 5
1
2
    // value must be greater thatn five
    assert i > 5;

When you have a switch, it is very common to forgive the default case, because you are not going to arrive that place. Maybe. What happens if anybody writes another option? We can be sure to manage them:

1
2
3
4
5
6
7
8
9
switch (var)
{
    case value1: do_stuff_1(); break;
    case value2: do_stuff_2(); break;
    ...
    case valueN: do_stuff_N(); break;

   default: assert False, "You must not be here!";
}

Preconditions and Postconditions

One of my favourite uses is to check inputs and outputs. For example, we have a function that returns the factorial of a given number, and it must be sure that input is bigger than 1 (and not negative). If it is not a public method:

1
2
3
4
5
def factorial (n):
  assert n > 0, "Invalid value:" + n;

  if n == 1: return 1
  return n * factorial (n-1)

We can assure we didn’t leave an invalid value:

1
2
3
4
5
6
7
8
protected List method () {
  ArrayList result = null;

  // Do lots of stuff, with ifs, method calls, etc.

  assert result != null, "Not initialized value";
  return result;
}

With Java, you can have some synchronized and no synchronized methods calling between them. It may be the root of every deathlock, that are very difficult to detect, because they are waiting for themselves to leave the lock. It is like to search your glasses with your glasses put on.

This case is really easy to detect with an assert:

1
2
3
4
5
6
7
8
9
protected synchronized void synchronized_method() {
  not_syncronized_method();
}

protected synchronized void not_synchronized_method() {
  assert Thread.holdsLock(this);

  // do some stuff
}

Disabling

In the last term, this assertions can be deactivated when you have a production enviroment, so it does not mind if you do “expensive” stuff. When you disable them, it is like they are not written.

Python ENABLEs them by default. You need to use -O option to disable them:

1
2
3
4
5
6
7
8
9
$ cat assert.py
assert False, "Asserts enabled"
$ python assert.py
Traceback (most recent call last):
  File "assert.py", line 1, in
    assert False, "Asserts enabled"
AssertionError: Asserts enabled
$ python -O assert.py
$

Java DISABLEs them by default, so you can activate them by module, method, etc. The easiest way is using -ea option to enable every assertion.

Use them lovely!!