How to get the unit test method name at runtime fr

2019-02-02 06:34发布

How to get the unit test name from the within unit test?

I have the below method inside a BaseTestFixture Class:

public string GetCallerMethodName()
{
    var stackTrace = new StackTrace();
    StackFrame stackFrame = stackTrace.GetFrame(1);
    MethodBase methodBase = stackFrame.GetMethod();
    return methodBase.Name;
}

My Test Fixture class inherits from the base one:

[TestFixture]
public class WhenRegisteringUser : BaseTestFixture
{
}

and I have the below system test:

[Test]
public void ShouldRegisterThenVerifyEmailThenSignInSuccessfully_WithValidUsersAndSites()
{
    string testMethodName = this.GetCallerMethodName();
    //
}

When I run this from within the Visual Studio, it returns my test method name as expected.

When this runs by TeamCity, instead _InvokeMethodFast() is returned which seems to be a method that TeamCity generates at runtime for its own use.

So how could I get the test method name at runtime?

5条回答
The star\"
2楼-- · 2019-02-02 06:51

If you are using NUnit 2.5.7 / 2.6 you can use the TestContext class:

[Test]
public void ShouldRegisterThenVerifyEmailThenSignInSuccessfully()
{
    string testMethodName = TestContext.CurrentContext.Test.Name;
}
查看更多
The star\"
3楼-- · 2019-02-02 06:51

Thanks guys; I used a combined approach so it now works in all environments:

public string GetTestMethodName()
{
    try
    {
        // for when it runs via TeamCity
        return TestContext.CurrentContext.Test.Name;
    }
    catch
    {
        // for when it runs via Visual Studio locally
        var stackTrace = new StackTrace(); 
        foreach (var stackFrame in stackTrace.GetFrames())
        {
            MethodBase methodBase = stackFrame.GetMethod();
            Object[] attributes = methodBase.GetCustomAttributes(
                                      typeof(TestAttribute), false); 
            if (attributes.Length >= 1)
            {
                return methodBase.Name;
            }
        }
        return "Not called from a test method";  
    }
}
查看更多
Bombasti
4楼-- · 2019-02-02 06:55

If you are not using NUnit you can loop over the stack and find the test method:

foreach(var stackFrame in stackTrace.GetFrames()) {
  MethodBase methodBase = stackFrame.GetMethod();
  Object[] attributes = methodBase.GetCustomAttributes(typeof(TestAttribute), false);
  if (attributes.Length >= 1) {
    return methodBase.Name;
  } 
}
return "Not called from a test method";
查看更多
疯言疯语
5楼-- · 2019-02-02 06:55

If you are not using Nunit or any other third party tool. you will not get TestAttribute.

So you can do this to get Test Method name. Use TestMethodAttribute insted of TestAttribute.

    public string GetTestMethodName()
    {
            // for when it runs via Visual Studio locally
            var stackTrace = new StackTrace();
            foreach (var stackFrame in stackTrace.GetFrames())
            {
                MethodBase methodBase = stackFrame.GetMethod();
                Object[] attributes = methodBase.GetCustomAttributes(typeof(TestMethodAttribute), false);
                if (attributes.Length >= 1)
                {
                    return methodBase.Name;
                }
            }
            return "Not called from a test method";
    }
查看更多
够拽才男人
6楼-- · 2019-02-02 07:10

When using Visual Studio to run your tests if you add a TestContext property in your test class you can get this information easily.

[TestClass]
public class MyTestClass
{
    public TestContext TestContext { get; set; }

    [TestInitialize]
    public void setup()
    {
        logger.Info(" SETUP " + TestContext.TestName);
        // .... //
    }
}
查看更多
登录 后发表回答