From the blog

RZAssert Yourself: Supercharge Your Assertions with New Macros from the Fine Folks at Raizlabs

As a codebase grows in size and complexity, every new line of code poses an incremtertally greater risk of breaking existing functionality. For developers working together on a project, the question quickly arises: “how do I not break stuff?” Developers have two core tools at their disposal to mitigate this risk: unit testing and assertions. This post will outline some of the reasons to use assertions in your code, and introduce our new assertion library, RZAssert.

Why Assertions?

Assertions make debugging easier by triggering exceptions immediately when the program enters an invalid state. Assertions work best when used aggressively. State should be checked wherever possible to ensure that state-dependent UI is behaving as expected. From another perspective, assertions are a way of writing down and checking a programmer’s own understanding of the code. Most often, assertions check preconditions (what we expect to be true before a piece of code runs), invariants (what we expect to be true at every iteration of a loop), or postconditions (what we expected to be true after a piece of code runs).

While unit tests can help us observe state for an individual module, these tests depend on dummy data and lack the ability to catch bugs that arise from interaction among separate modules. When an assertion fails, it gives us specific information as to what the immediate cause of the error was. More importantly, when assertions are used aggressively we are able to identify the error as early as possible in the flow of code, making it much easier to identify and fix the root cause.

RZAssert > NSAssert

Foundation defines NSAssert, a macro that acts as a front end for NSAssertionHandler. NSAssert takes a condition and a format string containing an error message.

NSAssert is flexible, but it requires us to write a new custom assertion every time we want to inspect state. Because assertions usually come in one of just a handful of flavors (true/false, empty/nonempty, type, etc), using NSAssert starts to produce a multitude of slightly different assertions as a codebase matures. Moreover, if we truly want to be aggressive in our use of assertions, typing out a new condition/description pair every time we want to inspect state becomes time consuming and can disguise common intent across multiple NSAsserts that share the same condition. We’ve found that in order for assertions to be used effectively, the process has to be as easy and convenient as possible.

Enter RZAssert

RZAssert adds ease of implementation and clarity of intent to your assertions. RZAssert defines macros which, like comments, express intent, but never go out of date. RZ_ASSERT_TRUE, RZ_ASSERT_FALSE, RZASSERT_NOT_NIL, and RZASSERT_NONEMPTY_STRING all do exactly what you think they do.

But There’s More:

RZAssert includes more exciting assertions that come in handy in a variety of contexts. For example:

You define a method on a class, but you want that method to ONLY be called on subclasses. Use RZASSERT_SUBCLASSES_MUST_OVERRIDE to throw an exception if the method is called from the class itself:

You define a switch statement with a case that should never occur. Use RZASSERT_SHOULD_NEVER_GET_HERE to throw an exception if your program passes the undesired case to the switch statement:

You define a method which takes a class instance as one of its arguments, and you want to confirm that the instance conforms to a specific protocol. We use RZASSERT_CONFORMS_PROTOCOL to throw an exception if the program passes a nonconformant instance to the method:

Where RZAssert is going

Source code for RZAssert lives here. Our hope for this assertion library is that it grows to include functionality that will make debugging even more effective: the ability to log assertion failures in production to a log file, the ability to send up assertions in production to an analytics backend like Crittercism, tagging for groups of related assertions, and more. We encourage you to use RZAssert in your own project by including it in your Podfile. Pull requests are welcome.

Leave a Reply

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