I recently came across some newly written code that was interspersed with lots of Debug.Assert (C#).
Should we still use this widely despite the usage of TDD, BDD and Unit Testing in general?
Software Engineering Stack Exchange is a question and answer site for professionals, academics, and students working within the systems development life cycle. It only takes a minute to sign up.
Sign up to join this communityI recently came across some newly written code that was interspersed with lots of Debug.Assert (C#).
Should we still use this widely despite the usage of TDD, BDD and Unit Testing in general?
I don't see any reason why you shouldn't use Assert. By doing so you've already acknowledged a need for guards, like preconditions & invariants, and are making a move towards Design by Contract. Assert is only one way of achieving this...
// Precondition using Asert
void SomeMethod(Foo someParameter)
{
Debug.Assert(someParameter != null)
}
// Precondition using If-Then-Throw
void SomeMethod(Foo someParameter)
{
if (someParameter == null)
throw new ArgumentNullException("someParameter");
}
// Precondition using Code Contracts
void SomeMethod(Foo someParameter)
{
Contract.Requires(someParameter != null);
}
// Precondition using some custom library
void SomeMethod(Foo someParameter)
{
Require.ArgumentNotNull(() => someParameter);
}
All are ways of achieving the same thing: robustness in code. It just comes down to choosing an option, of which Assert is a valid choice.
Note that I have not mentioned unit tests at all so far, as they accomplish something very different. A unit test formally proves the robustness of the code by exercising a guard:
[Test]
void SomeMethod_WhenGivenNull_ThrowsArgumentNullException()
{
delegate call = () => someObject.SomeMethod(null);
Assert.That(call).Throws<ArgumentNullException>();
}
This is an entirely different kind of assert...
**Note that in some frameworks it's actually quite difficult to unit test for an assertion failure, as an assertion failure can bring down the entire runtime, so one of the other options might be preferred...*
I consider asserts and unit tests to be two different tools in my toolbox. Some things are better suited to one, and some are better suited to the other.
As an example, these days I mostly make use of asserts to validate parameters for non-public methods.
I view Debug.Assert as premature optimization nowadays. Unless you really need the performance, suppressing the Assert in release mode can hide bugs for longer.
As MattDavey points out code contracts can be a superior, providing static checking instead of dynamic checking, and if not available I'd prefer Trace.Assert or a plain old if(x) throw SomeException;
Debug
class to be skipped from compilation... so suppressing calls to Assert
simply for performance is not just premature optimization, it is a plain nonsense.
Jan 10, 2013 at 12:47