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

时间:2015-02-19 21:31:23

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

我正在为Coded UI项目编写自定义记录器(尽管它也可能适用于单元测试项目)。在我的Logger类的FinishTestLog()方法中,我能够访问TestContext(使用其他地方提供的引用并存储在私有字段中)并获取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块中,这将是很好的。此信息是隐藏在TestContext或其他对象中的某个位置吗?

1 个答案:

答案 0 :(得分:2)

对于迟到的回答感到抱歉,但这可能对其他人有所帮助。我们通过在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;
    }