Reputation: 21756
TestContext.CurrentContext.Test
has several properties like FullName which can be parsed to get the current test method within NUnit. However, these don't help at all when the test's name is overridden using the TestName property on the TestCase attribute.
Is there a simple way to get the MethodInfo for the current test method from within an NUnit test? I can't simply use a stack trace, because I need this information in SetUp and TearDown when the test method is not on the stack.
I'm using NUnit 2.6.2
Upvotes: 2
Views: 1046
Reputation: 1264
In NUnit 3 (not sure about the older 2.x.y versions), there is a MethodName property in the TestAdapter class TestContext.CurrentContext.Test.MethodName
, that contains the original method name.
If I need to pass more information to my tests, especially for conditional setup, I'm using properties:
[Test, Property("SpecialTest", 1)]
public void MySpecialTest() {}
in conjunction with two little extension methods:
internal static class TestExtensions
{
public static bool TestHasProperty(this TestContext context, string propName) => context.Test.HasProperty(propName);
public static bool HasProperty(this TestAdapter test, string propName) => test.Properties.ContainsKey(propName);
}
Then I set it up accordingly:
[SetUp]
public void SetupEachTest()
{
if (TestContext.CurrentContext.TestHasProperty("SpecialTest"))
{
DoSpecialSetup();
}
}
Upvotes: 0
Reputation: 5223
NUnit by default does not provide such information - but it can be queries via private fields and properties. Following code could be used for example (Tested with NUnit 3.13.2):
/// <summary>
/// Accesses private class type via reflection.
/// </summary>
/// <param name="_o">input object</param>
/// <param name="propertyPath">List of properties in one string, comma separated.</param>
/// <returns>output object</returns>
object getPrivate(object _o, string propertyPath)
{
object o = _o;
var flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
foreach (var name in propertyPath.Split('.'))
{
System.Type type = o.GetType();
if (char.IsUpper(name[0]))
o = type.GetProperty(name, flags).GetValue(o);
else
o = type.GetField(name, flags).GetValue(o);
}
return o;
}
[SetUp]
public void EachSpecSetup()
{
var mi = (MemberInfo)getPrivate(TestContext.CurrentContext.Test, "_test.Method.MethodInfo");
// Alternative method - using Exposed nuget package:
//dynamic test = Exposed.From(TestContext.CurrentContext.Test)._test;
//dynamic method = Exposed.From(test)._method;
FactAttribute attr = mi.GetCustomAttribute<FactAttribute>();
string path = attr.FilePath;
string funcName = attr.FunctionName;
}
Like mentioned in code above it's also possible to use Exposed.From
- but main example should be theoretically faster.
Code will throw exception if any field / property is not valid - and this is intentional - use Visual studio watch window to identify type / field / properties.
Upvotes: 0
Reputation: 2538
One thing that comes to my mind is writing a custom NUnit EventListener
addin.
Then you could hook into the runcycle of the test runner and at least on the TestStarted
overload you will have the TestName
object. This won't have the MethodInfo available directly, but you may get it by playing around with the given properties there.
Good luck!
Upvotes: 0