Never 'assert' a statement with side effects!


 Every once in awhile, while whisking away at a new batch of code, the best of your wit fails you and you plant the seed for what would be an epic, head-ache inducing bug by not following a good common practice you really ought to know better about.

 Recently, I had to track down such a tragic blunder on my part, and I wasn't amused at myself when I recalled my justification for doing so.

The offending line of code was this:

assert list.Destroy()

Imagine my dismay when the behavior of the program was completely different when built for release than when built for testing.

On the outset, it looks pretty harmless. The idea in my mind was simple. "Ok, so I need to clean up and destroy this window, and it should always succeed given my assumptions, so why don't I just assert that it returns True for success? That way if something is wrong with the window, I'll catch the problem in my testing!" But I was lazy. Apparently too lazy to do the proper thing:

result = list.Destroy()
assert result

Remember: when __debug__ = False (such as during a release build), the entire assert becomes a no opt, and list.Destroy is never called.

The rule is simple when avoiding these kinds of disasterous headaches. Never, ever, under any circumstances, despite any laziness on your part, ever ever ever assert a statement with side effects. Don't even think about it pal!