简体   繁体   中英

Handling exceptions when running nunit tests from console application

I'm trying to run nunit test cases from the console application using reflection. I get an exception which is not handled by my catch block. Could you give an advice how to handle all the exceptions from the invoked test methods?

static void Main(string[] args)
{
    // Take all classes of the current assebly to which TestFixture attribute is applied
    var testClasses = Assembly.GetExecutingAssembly().GetTypes().Where(c =>
    {
        var attributes = c.GetCustomAttributes(typeof(TestFixtureAttribute));
        return attributes.Any();
    });
    foreach (var testClass in testClasses)
    {
        var testMethods = testClass.GetMethods().Where(m =>
        {
            var attributes = m.GetCustomAttributes(typeof (TestAttribute));
            return attributes.Any();
        });
        var instance = Activator.CreateInstance(testClass);
        foreach (var method in testMethods)
        {
            try
            {
                Action action = (Action) Delegate.CreateDelegate(typeof (Action), 
                                                                 instance, method);
                action();
            }
            catch (AggregateException ae)
            {
                Console.WriteLine(ae.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

It's really unclear why you're trying to do this, since there's already nunit-console that can run unit tests from a console application. It's also unclear what exception you don't think is being caught, but I suspect it's not the type you think it is. I took your code and put it into a fresh console application, along with some very basic tests:

[TestFixture]
public class SomeFailingTests
{
    [Test]
    public void Fails()
    {
        Assert.AreEqual(1, 0);
    }

    [Test]
    [ExpectedException(typeof(ArgumentException))]
    public void TestExceptionExpected()
    {
    }

    [Test]
    public void TestThrows()
    {
        throw new InvalidOperationException();
    }

    [Test]
    [ExpectedException(typeof(InvalidOperationException))]
    public void TestThrowsExpected()
    {
        throw new InvalidOperationException();
    }
}

All of the tests that threw exceptions were caught by the line:

catch (Exception e)

This makes sense, since none of them threw an AggregateException . I suspect whichever test you are running is also not throwing one and is also being caught by your outer catch. A good start might be to rewrite this block as:

catch (Exception e)
{
    Console.WriteLine(string.Format("{0}: {1}", e.GetType().Name, e.Message));
}

So that you can see any exception types that you aren't handling. At a very basic level, you may have to account for AssertionException for example.

If you want to support a similar feature set to other nunit runners you're also going to need to pay attention to the ExpectedException attribute on any methods you run and check to see if that exception is thrown when you invoke the method. You'll also need to check for the Ignored attribute...

As has been mentioned in my answer to this question , you may also need to pay attention to other test attributes such as TestCase and TestCaseSource if you want to capture all of the tests in the assembly.

Unless you're writing this as a learning exercise, you might want to reconsider your approach.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM