【问题标题】:How to get unit test method attributes at runtime from within an NUnit test run?如何在运行时从 NUnit 测试运行中获取单元测试方法属性?
【发布时间】:2012-08-01 15:33:00
【问题描述】:

我将有关给定测试的各种信息(多个错误跟踪系统的 ID)存储在一个属性中,如下所示:

[TestCaseVersion("001","B-8345","X543")]
public void TestSomethingOrOther()

为了在测试过程中获取这些信息,我编写了以下代码:

     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;
                }
            }
        }

问题是当在Release模式下通过NUnit运行测试时,应该有测试名称和这些属性的方法被以下替换:

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 属性的现有代码:

[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"];
}

【问题讨论】:

  • 不错的更新!!!如果可以的话,我会给你第二次投票:-)

标签: c# reflection attributes nunit


【解决方案1】:

如果您可以使用单值测试用例版本字符串(即"001, B-8345, X543" 而不是"001","B-8345","X543"),您应该能够利用NUnit 2.5 中提供的TestContext 功能。 7 或更高。

具体来说,您可以像这样定义和使用测试上下文Property 属性TestCaseVersion

[Test, Property("TestCaseVersion", "001, B-8345, X543")]
public void TestContextPropertyTest()
{
    Console.WriteLine(TestContext.CurrentContext.Test.Properties["TestCaseVersion"]);
}

更新顺便说一句,如果您确实想要使用测试用例版本的多值表示,您可以定义多个属性,如下所示:

[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"]);
}

【讨论】:

  • 谢谢,这也是我能找到的唯一解决方案。我希望有一种方法可以获取实际测试方法的任何其他属性,但这必须这样做
【解决方案2】:

可能我不明白你的想法,但为什么不使用更简单的解决方案呢?

[TestCase(TestName = "001, B-8345, X543")]
public void TestSomethingOrOther()

【讨论】:

  • 我对 NUnit TestContext 中的 TestName 很满意,但我想通过将它们添加到属性中来提供多个附加值。如果我在 TestCase 属性中使用它们,我必须将它们作为参数添加到测试方法中,并且如果不向每个测试添加额外的代码,它们仍然无法访问。
  • 但是你将如何使用GetTestID(),添加附加信息来断言消息?
  • 我在所有测试调用的方法上使用 GetTestID 来记录测试结果。
猜你喜欢
  • 2012-03-28
  • 2012-11-28
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
相关资源
最近更新 更多