Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ensure a Debug.Assert fires correctly using NUnit

Tags:

c#

c#-4.0

nunit

I've been trying to wrap my head around this issue: How to create a unit test that tests if a function aborts because a Debug.Assert (from System.Diagnostics) fails, marking it as passed when it does this and as failed if it doesn't.

I knowNUnit has the feature [ExpectedException(typeof( ArgumentException ) )], but I cannot seem to find out what kind of exception it is from the MSDN website. Intuition would say it might be something like an AssertionException, and that one does exist... but is part of the NUnit framework. I guess that's the exception NUnit assert throw around. I might be able to just nuke it by using:

[ExpectedException(typeof(Exception))]

But this gives rise to the problem that the standard windows debugging window shows up. In my search I came across ways to remove this window from showing up at all, but this feels like taking a butcheringknife to the surgerytable where you normally use a scalpel. Because I do want to be able to see this window when something unexpected happens, when I would execute my program.

I guess there is the workaround of replacing the Debug.Assert method with the NUnit counterpart (I'm still early in my project, so it's not a too big of a refactoring), but I assume a lot of programmers stick with Debug.Assert functionality as it's standard in .NET.

As such, I'd like to know how to 'assert' Debug.Assertion failures, without having to 'murder' the Windows debugging screen from my project?

To have an concrete example from a contract in my code, there is a sample below. For those it might seem familiar, it is the To-Wound table from Warhammer 40K tabletop wargame written as a function.

static public int assaultToHit(int _attacker_WeaponSkill,
            int _defender_WeaponSkill)
        {
            //Preconditions
            Debug.Assert(_attacker_WeaponSkill >= 1 && _attacker_WeaponSkill <= 10,
                "Weapon Skill stat must be in range [1,10]");
            Debug.Assert(_defender_WeaponSkill >= 1 && _defender_WeaponSkill <= 10,
                "Weapon Skill stat must be in range [1,10]");

            int target;
            if (_attacker_WeaponSkill > _defender_WeaponSkill)
            {
                target=3;
            }
            else if (_defender_WeaponSkill >= (_attacker_WeaponSkill + _attacker_WeaponSkill + 1))
            {
                target=5;
            }
            else
            {
                target=4;
            }

            //postconditions
            Debug.Assert(target >= 3 && target <= 5,
                "To hit target for assault must be in range [3,5]");

            return target;
        }

The function to test the preconditions would be in the line of something like this:

    [TestCase(-1,2)]
    [TestCase(1, -2)]
    [TestCase(-1, -2)]
    [TestCase(11, 2)]
    [TestCase(1, 20)]
    [TestCase(11, 20)] 
    [ExpectedException(typeof(Exception))]
    public void testContract_AssaultToHit(int _attacker_weaponskill, 
        int _defender_weaponskill)
    {
        Warhammer40kRules.assaultToHit(_attacker_weaponskill, 
            _defender_weaponskill);
    }
like image 939
Xilconic Avatar asked Feb 10 '12 15:02

Xilconic


People also ask

How do I use assert in NUnit?

NUnit Assert class is used to determine whether a particular test method gives expected result or not. In a test method, we write code the check the business object behavior. That business object returns a result. In Assert method we match the actual result with our expected result.

How does a debug assert work?

Assert is typically used when debugging to test an expression that should evaluate to True. If it doesn't, the Immediate window can be used to investigate why the test failed. Debug. Assert executes only when an application is run in the design-time environment; the statement has no effect in a compiled application.

What is debug assert in C#?

The Debug. Assert method in the System. In a debug compilation, Assert takes in a Boolean condition as a parameter, and shows the error dialog if the condition is false. The program proceeds without any interruption if the condition is true .


1 Answers

It seems you have used wrong facilities to control an application flow in case of an error. Debug.Assert() should not be used to drive an application logic flow.

Unit Test should cover a real test case and it seems either you're trying to implement wrong test case or you need to throw an exception/etc rather than using Debug.Assert(). You can share some code so it would be possible give you some specific advices.

Anyway you can read MSDN about how-to add a custom trace listener and intercept Assert calls.

Useful links:

  • Debug.Assert Method
  • Walkthrough: Creating a Custom Trace Listener
like image 74
sll Avatar answered Nov 02 '22 22:11

sll