Are Assertions Always Bad

Are assertions always bad?

We use a modified version of assert, as per JaredPar's comment, that acts like a contract. This version is compiled into the release code so there is a small size overhead, but disabled unless a diagnostics switch is set, such that performance overhead is minimized. Our assert handler in this instance can be set to disabled, silent mode (e.g. log to file), or noisy mode (e.g. display on screen with abort / ignore, where abort throws an exception).

We used automated regression testing as part of our pre-release testing, and asserts are hugely important here as they allow us to find potential internal errors that cannot be picked up at a GUI level, and may not be initially fatal at a user level. With automation, we can run the tests both with and without diagnostics, with little overhead other than the execution time, so we can also determine if the asserts are having any other side effects.

One thing to be careful of with asserts is side effects. For example, you might see something like assert(MyDatabasesIsOk()), which inadvertently corrects errors in the database. This is a bug, as asserts should never change the state of the running application.

Is assert evil?

No, there's nothing wrong with assert as long as you use it as intended.

That is, it's supposed to be for catching cases that "can't happen", during debugging, as opposed to normal error handling.

  • Assert: A failure in the program's logic itself.
  • Error Handling: An erroneous input or system state not due to a bug in the program.

Is using assert() in C++ bad practice?

Assertions are entirely appropriate in C++ code. Exceptions and other error handling mechanisms aren't really intended for the same thing as assertions.

Error handling is for when there's a potential for recovering or reporting an error nicely to the user. For example if there's an error trying to read an input file you may want to do something about that. Errors could result from bugs, but they could also simply be the appropriate output for a given input.

Assertions are for things like checking that an API's requirements are met when the API wouldn't normally be checked, or for checking things the developer believes he's guaranteed by construction. For example if an algorithm requires sorted input you wouldn't normally check that, but you might have an assertion to check it so that debug builds flag that kind of bug. An assertion should always indicate an incorrectly operating program.


If you're writing a program where an unclean shutdown could cause a problem then you may want to avoid assertions. Undefined behavior strictly in terms of the C++ language doesn't qualify as such a problem here, since hitting an assertion is probably already the result of undefined behavior, or the violation of some other requirement which could prevent some clean-up from working properly.

Also if you implement assertions in terms of an exception then it could potentially be caught and 'handled' even though this contradicts the very purpose of the assertion.

Is it good practice to use assert in Java?

The main reason assertions are not used is because they are not enabled by default. Therefore if you have a condition that is important enough to require an assertion you can't rely on assertions being enabled to get the job done.

As other answers have correctly stated they're designed for development-time testing and debugging because they cost nothing if assertions are disabled in production. I think it's better to create explicit tests in your testing framework (e.g. a unit test for edge conditions) than rely on someone enabling assertions while testing.

However a good example I've seen for using assertions is checking private method arguments. Since you control the access to those methods you can check that your own class is using the method correctly while your public methods use more reliable argument checking techniques (annotations, if statements, 3rd-party libraries, etc). That way even if assertions are disabled your method should be protected but developers looking at the source code can see the preconditions for your method and turn assertions on for an extra safety net when working on that class.

What does the Java assert keyword do, and when should it be used?

Assertions (by way of the assert keyword) were added in Java 1.4. They are used to verify the correctness of an invariant in the code. They should never be triggered in production code, and are indicative of a bug or misuse of a code path. They can be activated at run-time by way of the -ea option on the java command, but are not turned on by default.

An example:

public Foo acquireFoo(int id) {
Foo result = null;
if (id > 50) {
result = fooService.read(id);
} else {
result = new Foo(id);
}
assert result != null;

return result;
}

Is Assert.Fail() considered bad practice?

For this scenario, rather than calling Assert.Fail, I do the following (in C# / NUnit)

[Test]
public void MyClassDoesSomething()
{
throw new NotImplementedException();
}

It is more explicit than an Assert.Fail.

There seems to be general agreement that it is preferable to use more explicit assertions than Assert.Fail(). Most frameworks have to include it though because they don't offer a better alternative. For example, NUnit (and others) provide an ExpectedExceptionAttribute to test that some code throws a particular class of exception. However in order to test that a property on the exception is set to a particular value, one cannot use it. Instead you have to resort to Assert.Fail:

[Test]
public void ThrowsExceptionCorrectly()
{
const string BAD_INPUT = "bad input";
try
{
new MyClass().DoSomething(BAD_INPUT);
Assert.Fail("No exception was thrown");
}
catch (MyCustomException ex)
{
Assert.AreEqual(BAD_INPUT, ex.InputString);
}
}

The xUnit.Net method Assert.Throws makes this a lot neater without requiring an Assert.Fail method. By not including an Assert.Fail() method xUnit.Net encourages developers to find and use more explicit alternatives, and to support the creation of new assertions where necessary.

What are assertions? and why would you use them?

Asserts are a way of explicitly checking the assumptions that your code makes, which helps you track down lots of bugs by narrowing down what the possible problems could be. They are typically only evaluated in a special "debug" build of your application, so they won't slow down the final release version.

Let's say you wrote a function that took a pointer as an argument. There's a good chance that your code will assume that the pointer is non-NULL, so why not explicitly check that with an assertion? Here's how:

#include <assert.h>

void function(int* pointer_arg)
{
assert(pointer_arg != NULL);

...
}

An important thing to note is that the expressions you assert must never have side effects, since they won't be present in the release build. So never do something like this:

assert(a++ == 5);

Some people also like to add little messages into their assertions to help give them meaning. Since a string always evaulates to true, you could write this:

assert((a == 5) && "a has the wrong value!!");

Exception Vs Assertion

Use assertions for internal logic checks within your code, and normal exceptions for error conditions outside your immediate code's control.

Don't forget that assertions can be turned on and off - if you care about things like argument validation, that should be explicit using exceptions. (You could, however, choose to perform argument validation on private methods using assertions, on the grounds that a violation at that point is due to an internal bug rather than an external error.)

Alternatively it's entire reasonable (IMO) to use exceptions for everything. I personally don't use assertions much at all, but it's a matter of personal preference to some extent. (There can certainly be objective arguments for and against assertions, but it's not sufficiently clear cut to remove preference altogether.)



Related Topics



Leave a reply



Submit