Method for handling exceptions in mstest

我与影子孤独终老i 提交于 2019-12-10 21:43:09

问题


I have a lot of tests writen in this format:

[TestMethod]
public void TestMethod1()
{
    try
    {
        DoShomething();
    }
    catch (Exception e)
    {
        WriteExceptionLogWithScreenshot( e );
    }
}

[TestMethod]
public void TestMethod2()
{
    try
    {
        DoAnotherShomething();
    }
    catch ( Exception e )
    {
        WriteExceptionLogWithScreenshot( e );
    }
}

I would like to unify this exception handling using something like

[TestCleanup]
public void Cleanup()
{
    // find out if an exception was thrown and run WriteExceptionLogWithScreenshot( e )
}

Then I could avoid writing try catch blocks in all methods.

Does mstest support something like this? anyone have an ideia about what I could do?


回答1:


This is simpler:

    private void TryTest(Action action)
    {
        try
        {
            action();
        }
        catch (Exception e)
        {
            WriteExceptionLogWithScreenshot(e);
            throw;
        }
    }

    [TestMethod]
    public void TestMethod1()
    {
        TryTest(new Action(() =>
        {
            DoSomething();
        }
        ));
    }

    [TestMethod]
    public void TestMethod2()
    {
        TryTest(new Action(() =>
        {
            DoAnotherSomething();
        }
        ));
    }

Be sure to re-throw the exception so the test fails. Notice the throw in the catch.




回答2:


While it is an easy and (thread) safe alternative to wrap the test code in a lambda like Kip's answer I've found that it makes the stack trace a little harder to read since you'll always have the anonomous labmda stuck in there. Also, it requires another nesting level and it just tickles my OCD nerves a little.

I'd love for this to be extensible in MSTest, and in something like XUnit or NUnit you can get around this. You could even do this Aspect Oriented by superimposing a wrapper method around each method being run using something like PostSharp (see here).

If you're stuck with MSTest for whatever reasons (we've got a few myself, "attaching" files, CI scripts having been setup etc) you could do this though.

Make use of the FirstChanceException which will catch any exception thrown. Now, what I propose here is not thread safe and a bit wacky but if you're like us, running single threaded tests and care more about ease of use than performance etc it might work for you, you could improve this by bundling the registrations etc with the test context.

Basically, what I did anyway is to have a global test class that hooks the FirstChanceExceptions and 'safekeeps' the last thrown exception, then I reference this in the cleanup method.

[TestClass]
public static class GlobalSetup
{
    [AssemblyInitialize]
    public static void Setup(TestContext context)
    {
        AppDomain.CurrentDomain.FirstChanceException += (s, e) => LastException = e.Exception;
    }

    public static Exception LastException { get; private set; }
}

Then in a base class which contains logic for cleaning up any test:

[TestCleanup]
public virtual void Cleanup()
{
    if (TestContext.CurrentTestOutcome != UnitTestOutcome.Passed && GlobalSetup.LastException != null)
    {
        var e = GlobalSetup.LastException;
        Log.Error(GlobalSetup.LastException, $"{e.GetType()}: {e.Message}\r\n{e.StackTrace}");
    }
}



回答3:


Recently I had the same issue. And I found that if you are using MSTest V2 you can easily extend TestMethod Attribute class and use it instead like:

public class LoggedTestMethodAttribute : TestMethodAttribute
{
   public override TestResult[] Execute(ITestMethod testMethod)
   {
      var results = base.Execute(testMethod);
      //you can loop through results and call
      //WriteExceptionLogWithScreenshot(e);
   }
}

I guess when you don't use DataRow attribute then you will always have just one result in array. You can then directly get exception from result item's property TestFailureException

After that you just need to decorate your test methods with [LoggedTestMethod] attribute instead of [TestMethod]



来源:https://stackoverflow.com/questions/37660311/method-for-handling-exceptions-in-mstest

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!