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

VS测试资源管理器始终用默认适配器发现测试,如何解决命名冲突?

自定义测试适配器冲突问题

我通过实现ITestExecutor和ITestDiscoverer编写了自定义测试适配器,代码如下:

public class MyDiscoverer : ITestDiscoverer
{
    public void DiscoverTests(IEnumerable<string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink)
    {
        foreach (var sourceDllPath in sources.Distinct().Where(x => x.EndsWith(".dll")))
        {
            var ass = Assembly.LoadFrom(source);
            var types = ass.GetTypes();
            foreach(var t in types)
            {
                foreach(var member in t.GetMembers)
                {
                    foreach(var testCase in GetTestCases(member))
                    {
                        var name = $"{ t.Namespace }.{ t.Name }.{ member.Name }";
                        discoverySink.SendTestCase(new TestCase(name, myURL, ass.Location));
                    }
                }
            }
        }
    }
}

将该适配器作为项目引用添加到测试项目后,使用VS测试资源管理器时,默认适配器似乎仍在运行,测试的命名和层级结构与上述代码不符。测试资源管理器中参数化测试TestCaseWithReturnValue和TestCaseWithoutReturnValue重复显示,执行测试时仅自定义ITestExecutor实现对应的测试运行,存在命名冲突。

请问:

  1. 是否可以禁用默认测试发现流程以避免冲突?
  2. 若不可行,需如何设置TestCase名称以适配默认适配器的命名规范?
  3. 测试资源管理器如何解析TestCase("My.Assembly.My.Namespace.MyType.MyMethod")中的正确结构?

问题解答

1. 禁用默认测试发现流程

可以禁用默认测试适配器,有两种有效方式:

  • 项目属性配置:右键测试项目→属性→测试,在"默认测试适配器"下拉框中选择你的自定义适配器;或者通过.runsettings文件全局配置,添加以下节点:
<RunSettings>
  <TestAdapters>
    <DisableDefaultAdapters>True</DisableDefaultAdapters>
    <Adapters>
      <Adapter FriendlyName="你的自定义适配器名称" />
    </Adapters>
  </TestAdapters>
</RunSettings>

配置后需在VS测试资源管理器中选择该.runsettings文件生效。

  • 特性局部标记:在特定测试类或方法上添加[TestAdapter("你的自定义适配器ID")],仅对标记的测试生效,适合局部禁用默认适配器。

2. 适配默认适配器的TestCase命名规范

默认测试适配器(如MSTest、xUnit)的测试名称核心规则是:

  • 全限定名格式为命名空间.类名.方法名,参数化测试需附加唯一参数标识(如方法名(参数值1,参数值2))
  • 需同时正确设置TestCase的FullyQualifiedName和DisplayName属性,而非仅构造函数传入的名称

修改自定义适配器的测试名称生成逻辑示例:

var fullyQualifiedName = $"{t.Namespace}.{t.Name}.{member.Name}";
// 参数化测试需补充参数信息,避免重名
var displayName = member.Name;
if (testCaseParameters.Any())
{
    displayName = $"{member.Name}({string.Join(", ", testCaseParameters)})";
    fullyQualifiedName += $"({string.Join(", ", testCaseParameters)})";
}

var testCase = new TestCase(fullyQualifiedName, myURL, ass.Location)
{
    DisplayName = displayName
};
discoverySink.SendTestCase(testCase);

3. 测试资源管理器解析TestCase结构的逻辑

VS测试资源管理器主要通过TestCase的以下属性解析层级结构:

  • FullyQualifiedName:测试的唯一标识,VS会按.分割该字符串,从右往左依次识别方法、类、命名空间,最终构建"命名空间→类→方法"的层级展示。如果格式不规范,会直接将整个字符串作为测试名称,无法生成正确层级。
  • Source:测试所在程序集的路径,用来关联测试与对应的程序集文件。
  • DisplayName:测试资源管理器中显示的友好名称,优先级高于FullyQualifiedName的显示内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 03:36:00