MS UnitTestFramework 检索和记录异常 c#

MS UnitTestFramework retrieve and log exceptions c#

我刚刚开始一个相当广泛的自动化项目,该项目使用 MS 的 UnitTestFramework。我注意到的一件事是,当我的代码(而不是我测试的应用程序)中出现错误时,框架会捕获该错误并以一种允许测试迭代完成的愉快方式使测试失败。但是,我希望能够在我的 log4net 日志中看到这些异常和堆栈跟踪,到目前为止,我还没有找到在我的测试清理中获取它们的方法(或者在我无意散布的 try catch 块之外的任何地方在每种方法中)。

有人知道如何将这些异常记录到我的日志中吗?

您可以使用 First-Chance 异常通知 通过 AppDomain.FirstChanceException Event -

This event is only a notification. Handling this event does not handle the exception or affect subsequent exception handling in any way. After the event has been raised and event handlers have been invoked, the common language runtime (CLR) begins to search for a handler for the exception. FirstChanceException provides the application domain with a first chance to examine any managed exception.

类似这样的东西(注意它在 a method marked as AssemblyInitialize, which means it runs once per test run 中,并且代码排除了测试失败时 MSTest 抛出的 AssertFailedException。您可能还想排除其他异常,否则可能日志中有很多 'noise'。)

[TestClass]
public class Initialize
{
    [AssemblyInitialize]
    public static void InitializeLogging(TestContext testContext)
    {
         AppDomain.CurrentDomain.FirstChanceException += (source, e) =>
         {
           if (e.Exception is AssertFailedException == false)
                LogManager.GetLogger("TestExceptions").Error(e.Exception);
         };
    }
}

如果您可以替换 [TestMethod] 属性,那么您可以定义自己的属性 MyTestMethod,例如,通过像这样从默认属性派生:

public class MyTestMethodAttribute : TestMethodAttribute
{
    public override TestResult[] Execute(ITestMethod testMethod)
    {
        TestResult[] testResults = base.Execute(testMethod);
        foreach (var testResult in testResults.Where(e => e.Outcome == UnitTestOutcome.Failed))
            testResult.LogOutput += $"Exception `{testResult.TestFailureException.GetType().Name}` with message `{testResult.TestFailureException.Message}`.";
        return testResults;
    }
}

随后的测试会在 Visual Studio 的测试资源管理器的标准输出面板中生成预期的日志消息 Exception TestFailedException with message Assert.Fail failed. Some exception text.

[TestClass]
public class Tests
{
    [MyTestMethod]
    public void Test()
        => Assert.Fail("Some exception text");
}

当测试并行执行时,该方法也适用。