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

如何使基于Microsoft.TestPlatform的自定义C#测试框架自动发现测试?

解决方案:让自定义测试框架支持Test Explorer自动发现

核心问题分析

Test Explorer的自动发现依赖测试平台在项目编译后主动调用测试发现器,你的当前实现大概率存在以下问题:

  • 发现器未被测试平台正确加载
  • 发现逻辑依赖测试运行时状态(而非纯静态扫描)
  • 缺少必要配置让测试平台识别你的扩展组件

具体修复步骤

1. 重构ITestDiscoverer实现纯静态扫描逻辑

发现器必须脱离测试运行上下文,仅通过反射扫描程序集中标记MyTestAttribute的方法,示例实现:

[ExtensionUri("executor://mytestframework/v1")]
[DefaultExecutorUri("executor://mytestframework/v1")]
public class MyTestDiscoverer : ITestDiscoverer
{
    public void DiscoverTests(IEnumerable<string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink)
    {
        foreach (var source in sources)
        {
            try
            {
                var assembly = Assembly.LoadFrom(source);
                foreach (var type in assembly.GetTypes())
                {
                    // 扫描所有标记自定义特性的公开实例方法
                    var testMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public)
                        .Where(m => m.GetCustomAttribute<MyTestAttribute>() != null);

                    foreach (var method in testMethods)
                    {
                        var testCase = new TestCase(
                            displayName: $"{type.FullName}.{method.Name}",
                            executorUri: new Uri("executor://mytestframework/v1"),
                            source: source)
                        {
                            CodeFilePath = type.Assembly.Location
                            // 可选:通过读取PDB获取方法行号,提升Test Explorer体验
                        };

                        discoverySink.SendTestCase(testCase);
                    }
                }
            }
            catch (Exception ex)
            {
                logger.SendMessage(TestMessageLevel.Error, $"扫描测试失败 [{source}]: {ex.Message}");
            }
        }
    }
}

2. 正确注册测试扩展组件

测试平台通过MEF加载扩展,需完成以下配置:

  • 在项目Properties目录下创建testplugin.manifest文件,内容:
{
  "ExtensionTypes": [
    {
      "TypeFullName": "你的命名空间.MyTestDiscoverer",
      "AssemblyName": "你的测试框架程序集名称"
    },
    {
      "TypeFullName": "你的命名空间.MyTestExecutor",
      "AssemblyName": "你的测试框架程序集名称"
    }
  ]
}
  • 将该文件的生成操作设置为Embedded Resource,确保嵌入到程序集中。

3. 确保测试平台能探测到你的框架

如果通过NuGet分发测试框架,需添加.targets文件确保项目编译后测试平台能找到扩展:

<Project>
  <ItemGroup>
    <TestPlatformExtension Include="$(OutputPath)\你的测试框架程序集名称.dll" />
  </ItemGroup>
</Project>

本地调试时,确保测试项目引用框架后,输出目录包含框架程序集及PDB文件。

4. 验证自动发现触发

Test Explorer默认在项目编译完成后自动触发发现,也可手动操作:

  • 点击Test Explorer中"Run All"旁的下拉菜单,选择"Discover Tests"
  • 查看Output窗口的"Tests"分类,排查是否有发现器加载失败或扫描错误日志

常见问题排查

  • 确认发现器类上的ExtensionUri与执行器的Uri完全一致
  • 确保发现器没有抛出未捕获异常,否则测试平台会跳过该组件
  • 检查测试项目与框架的目标框架版本是否兼容(如均为.NET 6+)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:35:02