C++ – When to use asserts vs unit tests or both

assertionscerror handlingunit testing

Background:

I'm creating my first C++ game project and I plan on calling a InitialThirdPartySystems() function to…well…intialize all third party systems to be used in my code lol. Within it I want to do some checks to make sure all systems are initializing properly. However, I'm not quite sure of the properly way to have these checks while also creating my unit tests for this function. For example, I would normally assert that all these systems initialize properly since my game will depend on these systems functioning properly:

void InitializeThirdPartySystems()
{
   assert(Init_System(), "Error: System not initialized!");
}

So this would work fine within my debug build, but since assertions will be turned off in my release build then this check will go away. To solve this, I could design the function to be tested like so:

bool InitializeThirdPartySystems()
{
   if (!Init_System())
   {
      LOG("System Failed!");
      return false
   }
   return true;
}

So now I can just have my unit test check to see if systems are initializing properly or not. However, I won't be running any automatic tests in the background for now so that means I would have to keep switching to my test project to build and test my code.

The third option would be to do both kinds of testing (asserts and if style checks for unit tests) which would cover all my bases and would be good so that I always have asserts double checking anything my tests might miss. However, this will bloat my code and I generally haven't seen things implemented this way by others.

Question:

What is typically the best way to go about asserting/testing your code? Are my options the only ones or is there other ways to go about this I'm missing? Thanks for any input.

Best Answer

Neither asserts nor unit tests are appropriate in that case. Both are meant to check that your code actually does what you want it to do. This is not part of your application, and only run at development/debugging time.

Unit tests check some small chunk of code does what is needed, provided other components are correct.

Asserts document that you designed your code so that some condition is always (meant to) be true at that time, taking into account the interactions between components.

A third party system failing to initialize is out of your direct control.

You just have to detect it (check a status ?, catch exception ?,...) and handle it (intelligently abort the program with appropriate information, propose some degraded mode, ...). This is part of your application release code and runs in production.

Related Topic