Search Unity

Unity 5.1 shipped with a brand new Assertion Library. In this post, we will explain what an assertion is and how you can use it to improve runtime error diagnostics in your games.

What is an assertion and why should I care?

An assertion is a method that checks for a condition. If the condition is true, the method returns and the execution continues. If something unexpected happens and the assumption in the condition is not met, a message is printed that shows the callstack and optionally a user specified message. Let’s look at an example:

If the referenced GameObject was not active, an error log message would be printed showing the callstack and specified message “Player GameObject is not active”.

Assertion message

Many developers know asserts from unit tests. In a unit tests written using the Arrange-Act-Assert pattern, it’s the final part of the test method, where you compare expected and actual results. Assertions are not just for tests, though. You can use them in production code as well to get warned, at runtime, when invariants are violated. However, not all asserts should be used in runtime code.

What about the assertion libraries from unit tests frameworks?

It is very likely that you have first encountered assertions in a unit tests framework. As an example, let’s take NUnit. NUnit has a rich and battle-tested library for asserting tests you write with it. A natural thing to ask is why wouldn’t you simply want to use this library to test your production code? There are few reasons for that and one simple answer: it’s not meant for that purpose.

NUnit assertions allow you to test many things. From simple equality comparisons through more complex operations on collections to testing throwing exceptions. That is all fine but it all makes it too slow for using it in runtime. Low level assertions need to be as lean as possible and not give any unnecessary overhead in execution. The assertion library was written to run with no extra memory allocation and unnecessary operations.

An important thing for an assertion library is the possibility to strip the method calls out from the release build. The assertions can be very useful for developers during the production, but will be meaningless for the end-users if they fail. When building your final build you would want to get rid of all the calls to assertions. You could potentially comment all of the code out, but that wouldn’t be too smart. Luckily, .NET has a conditional compilation mechanism for such situations. The assertions library is implemented with Conditional attribute that will only include the assertion call in the developer’s build of your players. It is, however, still possible to include the assertions by forcing it via a compilation option.

Last but not least, it’s common for unit test assertion libraries to be based on exceptions. An exception is thrown on a failure and the execution flow is broken. This, obviously, is not desired in runtime code. The assertion library has been integrated with the Unity logging system and in case of a failure, a message will be logged. It makes the library versatile for all the platforms Unity supports. It also means the assertions work on AOT platforms that do not support exceptions.

So, what is in the library?

The library offers a several type-specific comparison methods and a generic equality comparer. Some of the assertion methods:

  • AreEqual – generic comparer used for basic equality comparison. Uses default equality comparer.
  • AreApproximatelyEqual – approximate comparer that tolerates comparison error. Can be used to compare floating point numbers.
  • IsTrue – for quick and easy boolean variables checks.

All the methods can be found in the Assert documentation.

A cool thing about this library is it’s out-of-the-box compatibility with Unity Test Tools. Without any extra effort, the assertion will fail any integration tests calling the code guarded by them.

Extending the library

When you want to get the most out of a feature, it’s natural to want to extend it. The library’s AreEqual methods allow you to pass your own implementation of a comparer for a specific type. The comparer has to implement the IEqualityComparer interface.

The library comes with FloatComparer used for comparing floats. It also allows you to do comparison with a relative error check. This comparer is used by AreApproximatellyEqual method.

Wrap-up

Using assertion library to protect your code from bugs and undesired state is an easy and little-impact mechanism you can start using right away. The library will be improved with time and, as usual, your comments and suggestions are more than welcome!

Comments are closed.

  1. Thank you for this, this is good stuff and I hope this aspect of Unity continues to be improved.

    A suggestion I have is as follows:
    – I am using the UnityVS plugin, so I am happily debugging my C# Unity code in VS 2015.
    – If an Assert method fails (Assert.IsTrue( meaningOfLife == 42);) then can the assert cause the VS to breakpoint, stopping at the exact line where the Assert() method is?

    Or if the above is possible now, I’d love to know.

    Thanks.

  2. Hi Tomek,

    Can I make a feature request? It would be really cool to make Assert function calls to take UnityEngine.Object context as the last argument just like Debug.Log*() functions. By providing a context the developer can click on the log message and he can quickly identify the faulty object. This can be extremely useful when there are many scene objects with the same script and only part of them are failing the asserts.

    Thank you for your consideration!
    Piotr

  3. Hey this library seems very useful and it could be even more if it was compatible with Resharper and its Annotations. As you even include Resharper Annotation dll now with Unity, it would be great if Unity3D code made use of it !

  4. Peter Friedland

    August 28, 2015 at 2:12 pm

    I really appreceate this as well. Do you plan to make assertions internally as well? Will I be able to disable assertions separatly from debug mode?

    hopefully Assertions doesn’t affect performance so much!

  5. Its cool!
    But the reason I dont use tests in unity,
    Is because it doesnt show code coverage, and its hard to follow my tests this way..

  6. Thanks Tomek for the down-to-earth explanation, this is really useful. I hope Unity Test Tools get integrated natively in Unity.
    I however can’t help but notice that Unity is getting way more namespaces lately.

  7. It’s great to see some love given to the finer areas of programming with Unity, thanks.