You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何从C#读取IntelliSense内容及提取NUnit测试<summary>信息生成报告

我来帮你逐个解答这两个问题:

问题1:如何从C#中读取IntelliSense的内容?

IntelliSense展示的内容本质上来自代码的XML注释和程序集的元数据,要在C#里读取这些内容,主要有两种靠谱的方式:

  • 用Roslyn API直接分析代码/程序集
    Roslyn是.NET官方的编译器平台,能直接解析代码结构和元数据,轻松获取类、方法的注释信息。你需要引用Microsoft.CodeAnalysis相关的NuGet包,比如Microsoft.CodeAnalysis.CSharpMicrosoft.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文件匹配注释。步骤大概是:

    1. 用反射获取目标类型/方法的MemberInfo
    2. 调用GetDocumentationCommentId()拿到该成员在XML文档里的唯一ID;
    3. 加载XML文档文件,根据ID找到对应的<member>节点,提取<summary>内容。
问题2:Visual Studio 2015中NUnit测试报告包含描述信息

先说结论:NUnit默认的XML报告没法直接开箱即用地包含测试方法的summary注释,因为这些注释属于代码的XML文档,NUnit默认只会捕获测试的名称、结果、耗时这些运行时元数据。不过有两种可行的解决思路:

思路一:自定义NUnit扩展,运行时注入注释

你可以编写NUnit的自定义扩展,比如实现ITestAction接口,在测试执行前后通过反射读取测试方法的summary注释,然后把它附加到测试结果里。不过要注意,VS2015对应的NUnit版本可能是2.x或3.x,你需要适配对应的扩展API。

思路二:后处理XML报告,合并注释内容

这个方法更简单易上手,不需要修改NUnit的运行逻辑,步骤如下:

  1. 确保你的测试项目编译时生成XML文档文件(同上,在项目属性里开启);
  2. 用NUnit生成标准的XML测试报告(比如用nunit-console.exe运行测试,指定--result参数输出XML);
  3. 编写一个小工具,解析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

火山引擎 最新活动