You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用System.Reflection读取NUnit测试方法的Property与Category属性值

解决NUnit属性反射读取问题

我来帮你搞定这个反射读取NUnit属性的问题!你当前的代码主要有两个问题:一是用attr.ToString()判断属性类型不够可靠,二是不知道如何直接访问属性内部的键值数据。下面给你两种解决方案,分别适用于已经引用NUnit程序集和动态加载的场景。

方案一:直接引用NUnit.Framework程序集

如果你的项目已经引用了NUnit的NUnit.Framework.dll,可以直接通过类型匹配来读取属性值,代码更简洁直观:

using System;
using System.Reflection;
using NUnit.Framework; // 确保引用了这个命名空间

// ...

Assembly a = Assembly.LoadFile(dllPath);
var types = a.GetTypes();
foreach (Type type in types)
{
    foreach (MethodInfo methodInfo in type.GetMethods())
    {
        var attributes = methodInfo.GetCustomAttributes(true);
        foreach (var attr in attributes)
        {
            // 处理Test/TestCase属性
            if (attr is TestAttribute || attr is TestCaseAttribute)
            {
                // 你的原有逻辑代码
            }
            // 读取PropertyAttribute的TestDescription值
            else if (attr is PropertyAttribute propAttr)
            {
                // 精准获取指定键的值
                if (propAttr.Properties.TryGetValue("TestDescription", out var descValue))
                {
                    string testDescription = descValue.ToString();
                    Console.WriteLine($"测试描述:{testDescription}");
                    // 这里可以把值存入变量或做其他处理
                }

                // 如果需要遍历所有Property属性
                foreach (var kvp in propAttr.Properties)
                {
                    Console.WriteLine($"Property键:{kvp.Key},值:{kvp.Value}");
                }
            }
            // 读取CategoryAttribute的标签
            else if (attr is CategoryAttribute categoryAttr)
            {
                // 将逗号分隔的标签拆分为数组
                string[] categories = categoryAttr.Name.Split(
                    new[] { ',' }, 
                    StringSplitOptions.RemoveEmptyEntries
                );
                foreach (string tag in categories)
                {
                    string trimmedTag = tag.Trim();
                    Console.WriteLine($"测试标签:{trimmedTag}");
                }
            }
        }
    }
}

方案二:动态加载(不直接引用NUnit)

如果你的场景是动态加载DLL,不想直接引用NUnit程序集,可以通过反射动态访问属性的内部成员:

using System;
using System.Reflection;

// ...

Assembly a = Assembly.LoadFile(dllPath);
var types = a.GetTypes();
foreach (Type type in types)
{
    foreach (MethodInfo methodInfo in type.GetMethods())
    {
        var attributes = methodInfo.GetCustomAttributes(true);
        foreach (var attr in attributes)
        {
            Type attrType = attr.GetType();
            string attrFullName = attrType.FullName;

            // 处理Test/TestCase属性
            if (attrFullName == "NUnit.Framework.TestAttribute" || attrFullName == "NUnit.Framework.TestCaseAttribute")
            {
                // 你的原有逻辑代码
            }
            // 读取PropertyAttribute的值
            else if (attrFullName == "NUnit.Framework.PropertyAttribute")
            {
                // 动态获取Properties字典
                PropertyInfo propertiesProp = attrType.GetProperty("Properties");
                if (propertiesProp != null)
                {
                    var properties = (System.Collections.IDictionary)propertiesProp.GetValue(attr);
                    if (properties.Contains("TestDescription"))
                    {
                        string testDescription = properties["TestDescription"].ToString();
                        Console.WriteLine($"测试描述:{testDescription}");
                    }
                }
            }
            // 读取CategoryAttribute的标签
            else if (attrFullName == "NUnit.Framework.CategoryAttribute")
            {
                PropertyInfo nameProp = attrType.GetProperty("Name");
                if (nameProp != null)
                {
                    string categoryStr = (string)nameProp.GetValue(attr);
                    string[] categories = categoryStr.Split(
                        new[] { ',' }, 
                        StringSplitOptions.RemoveEmptyEntries
                    );
                    foreach (string tag in categories)
                    {
                        Console.WriteLine($"测试标签:{tag.Trim()}");
                    }
                }
            }
        }
    }
}

关键知识点说明

  • 避免用ToString()判断类型:attr.ToString()的输出可能因NUnit版本变化而改变,直接用类型匹配(is关键字)或全限定类名判断更可靠。
  • PropertyAttribute的结构:NUnit的PropertyAttribute内部用Properties字典存储所有键值对,直接通过键名就能取出对应的值。
  • CategoryAttribute的处理:当你用逗号分隔多个标签时,CategoryAttribute的Name属性是完整的字符串,需要拆分并修剪空格才能得到单个标签。

内容的提问来源于stack exchange,提问作者Ayan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:43:11