如何用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
相关产品推荐
相关产品推荐

