c# - 以编程方式从编码 UI/单元测试中获取错误消息/堆栈跟踪

标签 c# .net unit-testing logging visual-studio-2013

我正在为编码的 UI 项目编写一个自定义记录器(尽管它也可能适用于单元测试项目)。在 Logger 类的 FinishTestLog() 方法中,我能够访问 TestContext(使用其他地方提供并存储在私有(private)字段中的引用)并获取 CurrentTestOutcome,该结果将写入日志:

public static void FinishTestLog()

{ ...

String message;
if (_testContext != null)
{
    message = String.Format("Ended execution of test case with outcome: {0}",
        _testContext.CurrentTestOutcome.ToString());
}
else
{
    message = "Ended execution of test case";
}

...

}

有时测试会失败,在这种情况下,测试资源管理器将显示错误消息和堆栈跟踪,这些信息将写入 TRX 文件(如果已配置)。如果能够以与 TestContext.CurrentTestOutcome 相同的方式获取错误消息和堆栈跟踪,而不是将每个测试方法包装在 try/catch block 中,那就太好了。此信息是否隐藏在 TestContext 或其他对象中的某个位置?

最佳答案

很抱歉回答晚了,但这可能对其他人有帮助。我们通过在 TestContext 对象上使用 Reflection 来获取它。如果有人知道如何使用 NUnit 2.x,请告诉我。

    /// <summary>
    /// Returns Error Stack Trace Details extracted from TestContext
    /// </summary>
    /// <param name="testContext"></param>
    /// <returns></returns>
    public static string GetErrorStackTraceFromTestContext(TestContext testContext)
    {
        const BindingFlags privateGetterFlags = System.Reflection.BindingFlags.GetField |
                                                System.Reflection.BindingFlags.GetProperty |
                                                System.Reflection.BindingFlags.NonPublic |
                                                System.Reflection.BindingFlags.Instance |
                                                System.Reflection.BindingFlags.FlattenHierarchy;

        var m_message = string.Empty; // Returns empty if TestOutcome is not failed
        if (testContext.CurrentTestOutcome == UnitTestOutcome.Failed)
        {
            // Get hold of TestContext.m_currentResult.m_errorInfo.m_stackTrace (contains the stack trace details from log)
            var field = testContext.GetType().GetField("m_currentResult", privateGetterFlags);
            var m_currentResult = field.GetValue(testContext);
            field = m_currentResult.GetType().GetField("m_errorInfo", privateGetterFlags);
            var m_errorInfo = field.GetValue(m_currentResult);
            field = m_errorInfo.GetType().GetField("m_stackTrace", privateGetterFlags);
            m_message = field.GetValue(m_errorInfo) as string;
        }

        return m_message;
    }

获取错误消息的方法类似:

    /// <summary>
    /// Returns Error Message Details extracted from TestContext
    /// </summary>
    /// <param name="testContext"></param>
    /// <returns></returns>
    public static string GetErrorMessageFromTestContext(TestContext testContext)
    {
        const BindingFlags privateGetterFlags = System.Reflection.BindingFlags.GetField |
                                                System.Reflection.BindingFlags.GetProperty |
                                                System.Reflection.BindingFlags.NonPublic |
                                                System.Reflection.BindingFlags.Instance |
                                                System.Reflection.BindingFlags.FlattenHierarchy;

        var m_message = string.Empty; // Returns empty if TestOutcome is not failed
        if (testContext.CurrentTestOutcome == UnitTestOutcome.Failed)
        {
            // Get hold of TestContext.m_currentResult.m_errorInfo.m_message (contains the exception text that was thrown)
            var field = testContext.GetType().GetField("m_currentResult", privateGetterFlags);
            var m_currentResult = field.GetValue(testContext);
            field = m_currentResult.GetType().GetField("m_errorInfo", privateGetterFlags);
            var m_errorInfo = field.GetValue(m_currentResult);
            field = m_errorInfo.GetType().GetField("m_message", privateGetterFlags);
            m_message = field.GetValue(m_errorInfo) as string;
        }

        return m_message;
    }

关于c# - 以编程方式从编码 UI/单元测试中获取错误消息/堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28617317/

相关文章:

ruby-on-rails - Controller 测试使用 Rspec 显示页面,它给出错误 nil & 并渲染空页面

C# elseif 对比 else{if} 速度

c# - 如何正确获取android.net.Uri 的文件大小?

c# - WinRT Xaml ListView - 触摸不能很好地滚动

.net - 使用 .NET 创建带 JPEG 压缩的多页 TIFF

javascript - Dotnet 返回 URL 缺少参数

c# - 如何列出 ASP.NET Core 中的所有配置源或属性?

c# - 如何以线程安全的方式更新控件

java - 适用于非线程安全代码的执行器

django - 在 Django 模型中测试 'class Meta'