如何从C#读取IntelliSense内容及提取NUnit测试<summary>信息生成报告
我来帮你逐个解答这两个问题:
IntelliSense展示的内容本质上来自代码的XML注释和程序集的元数据,要在C#里读取这些内容,主要有两种靠谱的方式:
用Roslyn API直接分析代码/程序集
Roslyn是.NET官方的编译器平台,能直接解析代码结构和元数据,轻松获取类、方法的注释信息。你需要引用Microsoft.CodeAnalysis相关的NuGet包,比如Microsoft.CodeAnalysis.CSharp和Microsoft.CodeAnalysis.Workspaces。举个简单例子:using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; // 加载程序集或源代码 var workspace = new AdhocWorkspace(); var project = workspace.AddProject("MyProject", LanguageNames.CSharp); var compilation = project.GetCompilationAsync().Result; // 获取某个类型的符号 var typeSymbol = compilation.GetTypeByMetadataName("YourNamespace.YourClass"); if (typeSymbol != null) { // 获取类型的summary注释 var xmlDoc = typeSymbol.GetDocumentationCommentXml(); Console.WriteLine(xmlDoc); // 这里会包含<summary>等注释内容 }反射+XML文档文件
如果你的程序集编译时生成了对应的XML文档文件(项目属性→生成→输出里勾选“XML文档文件”),可以用反射拿到成员信息,再解析XML文件匹配注释。步骤大概是:- 用反射获取目标类型/方法的
MemberInfo; - 调用
GetDocumentationCommentId()拿到该成员在XML文档里的唯一ID; - 加载XML文档文件,根据ID找到对应的
<member>节点,提取<summary>内容。
- 用反射获取目标类型/方法的
先说结论:NUnit默认的XML报告没法直接开箱即用地包含测试方法的summary注释,因为这些注释属于代码的XML文档,NUnit默认只会捕获测试的名称、结果、耗时这些运行时元数据。不过有两种可行的解决思路:
思路一:自定义NUnit扩展,运行时注入注释
你可以编写NUnit的自定义扩展,比如实现ITestAction接口,在测试执行前后通过反射读取测试方法的summary注释,然后把它附加到测试结果里。不过要注意,VS2015对应的NUnit版本可能是2.x或3.x,你需要适配对应的扩展API。
思路二:后处理XML报告,合并注释内容
这个方法更简单易上手,不需要修改NUnit的运行逻辑,步骤如下:
- 确保你的测试项目编译时生成XML文档文件(同上,在项目属性里开启);
- 用NUnit生成标准的XML测试报告(比如用
nunit-console.exe运行测试,指定--result参数输出XML); - 编写一个小工具,解析XML报告和测试项目的XML文档,把每个测试方法的summary合并到报告里。
给你一段简化的示例代码,用XDocument来处理:
using System.Linq; using System.Xml.Linq; var nunitResultPath = "TestResult.xml"; var testXmlDocPath = "YourTestProjectName.xml"; // 加载两个XML文件 var nunitDoc = XDocument.Load(nunitResultPath); var xmlDoc = XDocument.Load(testXmlDocPath); // 遍历每个测试用例节点 foreach (var testCase in nunitDoc.Descendants("test-case")) { var fullMethodName = testCase.Attribute("fullname")?.Value; if (string.IsNullOrEmpty(fullMethodName)) continue; // 转换为XML文档里的member ID格式(比如M:Namespace.Class.MethodName(ParamType)) var memberId = $"M:{fullMethodName.Replace('.', '#').Replace('(', '`').Replace(')', '')}"; var memberNode = xmlDoc.Descendants("member") .FirstOrDefault(m => m.Attribute("name")?.Value == memberId); if (memberNode != null) { var summary = memberNode.Element("summary")?.Value.Trim(); if (!string.IsNullOrEmpty(summary)) { // 在测试节点里添加summary子节点 testCase.Add(new XElement("summary", summary)); } } } // 保存带summary的新报告 nunitDoc.Save("TestResult_WithSummary.xml");
注意:如果有方法重载,member ID里会包含参数类型的签名,你可能需要更精细地处理签名转换,确保能匹配到正确的XML节点。
内容的提问来源于stack exchange,提问作者javirs




