如何在运行时从NUnit测试运行中获取单元测试方法属性? [英] How to get unit test method attributes at runtime from within an NUnit test run?
问题描述
我将有关给定测试的各种信息(多个错误跟踪系统的ID)存储在这样的属性中:
I store various information about a given test (IDs for multiple bug tracking systems) in an attribute like so:
[TestCaseVersion("001","B-8345","X543")]
public void TestSomethingOrOther()
为了在测试过程中获取此信息,我编写了以下代码:
In order to fetch this information during the course of a test, I wrote the below code:
public string GetTestID()
{
StackTrace st = new StackTrace(1);
StackFrame sf;
for (int i = 1; i <= st.FrameCount; i++)
{
sf = st.GetFrame(i);
if (null == sf) continue;
MethodBase method = sf.GetMethod();
if (method.GetCustomAttributes(typeof(TestAttribute), true).Length == 1)
{
if (method.GetCustomAttributes(typeof(TestCaseVersion), true).Length == 1)
{
TestCaseVersion tcv =
sf.GetMethod().GetCustomAttributes(typeof(TestCaseVersion), true).OfType<TestCaseVersion>()
.First();
return tcv.TestID;
}
}
}
问题在于,当通过发布模式下的NUnit运行测试时,应具有测试名称和这些属性的方法将替换为以下内容:
The problem is that when running tests through NUnit in Release mode, the method which should have the test name and these attributes is replaced by the following:
System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at NUnit.Core.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
更新 对于任何有兴趣的人,我都会按照以下方式完成代码的实现(以便可以访问任何属性值,而无需更改任何使用TestCaseVersion属性的现有代码:
UPDATE For anyone who is interested, I wound up implementing the code in the following way (so that any of the attribute values could be accessed, without changing any of the existing code that uses TestCaseVersion attribute:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, AllowMultiple = false)]
public class TestCaseVersion : PropertyAttribute
{
public TestCaseVersion(string testCaseCode, string story, string task, string description)
{
base.Properties.Add("TestId", testCaseCode);
base.Properties.Add("Description", description);
base.Properties.Add("StoryId", story);
base.Properties.Add("TaskId", task);
}
}
public string GetTestID()
{
return TestContext.CurrentContext.Test.Properties["TestId"];
}
推荐答案
如果您可以使用单值测试用例版本字符串(即"001, B-8345, X543"
而不是"001","B-8345","X543"
),则应该可以使用 NUnit 2.5.7中可用的 TestContext 功能的介绍 em>及更高版本.
If you are OK with having a single-valued test case version string (i.e. "001, B-8345, X543"
instead of "001","B-8345","X543"
), you should be able to make use of the TestContext functionality available in NUnit 2.5.7 and higher.
具体来说,您可以定义和使用测试上下文属性属性 TestCaseVersion 像这样:
Specifically, you could define and use a test context Property attribute TestCaseVersion like this:
[Test, Property("TestCaseVersion", "001, B-8345, X543")]
public void TestContextPropertyTest()
{
Console.WriteLine(TestContext.CurrentContext.Test.Properties["TestCaseVersion"]);
}
更新顺便说一句,如果您想使用测试用例版本的多值表示形式,则可以定义多个属性,如下所示:
UPDATE BTW, If you do want to use a multi-valued representation of the test case version, you could define multiple properties, like this:
[Test, Property("MajorVersion", "001"),
Property("MinorVersion", "B-8345"), Property("Build", "X543")]
public void TestContextPropertyTest()
{
Console.WriteLine(TestContext.CurrentContext.Test.Properties["MajorVersion"]);
Console.WriteLine(TestContext.CurrentContext.Test.Properties["MinorVersion"]);
Console.WriteLine(TestContext.CurrentContext.Test.Properties["Build"]);
}
这篇关于如何在运行时从NUnit测试运行中获取单元测试方法属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!