研发协作
判断 .NET 项目使用哪个测试平台与框架(VSTest…
当需要识别 .NET 项目的测试平台、测试框架、dotnet test 命令模式以及 SDK 风格还是经典项目系统时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
判断 .NET 项目使用哪个测试平台与框通用
解决思路
- 先给出结论(Platform/Framework 等分类),不要在结论前加标题、草稿分析、工具语法或回显模板;随后用一句简洁的证据句列出支撑每个分类的仓库事实;当请求 Framework 时,要指出识别它的包或项目 SDK;只有在存在冲突、配置不完整或按目标框架有差异时才加第二句。
- Platform 指实际执行测试的平台:VSTest 或 MTP;若配置冲突或不完整导致无法执行,报告为 unavailable,而不是臆造一个成功平台。
- 绝不要仅凭 global.json 的 test.runner 判定实际执行平台;该设置只选择 dotnet test 命令模式,即使显式写 VSTest 也可能桥接到可执行的 MTP 应用;必须继续检查项目 runner、bridge 和输出形态信号后再写 Platform。
- 按用户请求的标签和顺序精确作答,用实际分类替换所有占位符;若请求的标签不含 dotnet test mode,则整段回答中不要提及或解释命令模式。
- 按请求范围裁剪证据:请求平台与框架时,给出最终 runner 选择器及其胜出来源、识别框架的包或项目 SDK,必要时给出使其可执行的属性,省略命令模式、通用 SDK 事实和 OutputType(除非缺失或冲突);只问单一决定信号时,给出该 runner 选择属性、其来源为何胜出、以及为何竞争包不选择或暗示 VSTest,仍要指出识别框架的包或项目 SDK,配置完整时省略 bridge、OutputType、SDK 模式和无关前置条件;按目标框架问平台时,只给按目标不同的条件最终值;问显式 opt-out 时,给最终 UseVSTest 值及其胜出来源;问 dotnet test 模式时,分别给出命令模式与执行平台分类。
- 当用户问在显式 runner 属性与 Microsoft.NET.Test.Sdk 之间哪个单一信号决定时,证据句必须同时说明 runner 属性选择 MTP,且 Microsoft.NET.Test.Sdk 不选择也不暗示 VSTest。
- 当导入优先级决定某属性时,要说明胜出来源为何胜出(例如它被更晚导入或其条件成立),而不只是说它包含最终值或覆盖了另一赋值。
- 把解释保持在请求的轴上:global.json 中的 SDK 版本固定只是上下文,不是平台选择器,只有其 test.runner 设置确实选择 VSTest 或原生 MTP 时才这样声称;若 UseVSTest=true 是决定性的,直接说明,不要推测缺失的 test.runner 或把 SDK 固定描述为额外的平台选择;若未请求命令模式,即使内部需要它来确定执行平台,也不要添加。
- 当经典项目请求还问命令族时,直接加一行如 Command family: MSBuild + vstest.console.exe,不要写成可选替代或加不必要的构建限定词。
- 对基于文件的请求,先枚举一次这些配置名:global.json、.csproj、packages.config、Directory.Build.props、Directory.Build.targets、Directory.Packages.props 以及显式导入的 .props/.targets,然后一次性批量读取所有存在的相关文件;项目文件中缺失的设置可能由导入定义,绝不要仅凭 .csproj 推断其最终值;仓库配置足够时不要搜索网络或检查无关文件。
- 按实际 MSBuild 导入顺序解析属性,而不是固定用“项目胜过 props”规则;对每个适用目标框架:1) 沿导入图和条件走,更晚的适用赋值胜出,Directory.Build.props 通常在项目主体之前导入,因此无条件项目赋值通常覆盖它,更晚的 .targets 又可再次覆盖项目;2) 记录 UseVSTest、框架 runner 选择器、TestingPlatformDotnetTestSupport 和 OutputType 的最终值及其胜出来源;3) 把 Directory.Packages.props 视为版本证据,除非它也含相关属性,先解析包/SDK 版本再应用依赖版本的默认值;4) 绝不要从包存在推断属性,包或 SDK 默认值只有在解析出的版本确实提供它且无更晚赋值覆盖时才计入。
- 在选择 CLI 前先分类项目系统:根 Sdk 属性或 <Sdk> 声明为 SDK 风格;ToolsVersion、Microsoft.Common.props/Microsoft.CSharp.targets 导入、显式 <Reference> 和 <Compile Include> 项为经典非 SDK;packages.config 为经典 NuGet 依赖管理。
- 经典项目仍可使用 VSTest 兼容适配器,但 dotnet test 不自动是有效调用;保留仓库脚本/CI 命令,通常是 MSBuild 后接 vstest.console.exe;仅当仓库配置或文档确立该旧式 runner 时才提 MSTest.exe。
- 检测测试框架:读取 .csproj、相邻 packages.config 以及 Directory.Build.props/Directory.Packages.props,查找:MSTest 元包、<Project Sdk="MSTest.Sdk[/version]"> 或 <Sdk Name="MSTest.Sdk"> 为 MSTest;MSTest.TestFramework + MSTest.TestAdapter 为 MSTest(v3/v4 也有效);xunit、xunit.v3、xunit.v3.mtp-v1、xunit.v3.mtp-v2、xunit.v3.core.mtp-v1、xunit.v3.core.mtp-v2 为 xUnit;NUnit + NUnit3TestAdapter 为 NUnit;TUnit 为 TUnit(仅 MTP)。
- 在经典项目中,包 ID 和版本可能只出现在 packages.config,而项目含带 HintPath 的程序集 <Reference> 元素;两个来源都要用。
- 若用户显式请求 dotnet test 模式,先读 references/command-mode.md 再回答;对仅问平台/框架的请求不要加载该引用或提及命令模式。
- 对 SDK 8/9 且显式问命令模式、无有效 bridge 的请求,用一句因果句说明三件事:runner 使项目具备 MTP 能力、dotnet test 仍处于 VSTest 模式、缺失 bridge 意味着 VSTest 实际执行测试;仅当有助于解释该结果时才提原生 MTP 命令模式从 SDK 10 开始。
- 当允许执行且提示或 global.json 都未指明 SDK 时,运行一次 dotnet --version;对禁止执行的只读识别请求,不要探测已安装 SDK,使用仓库事实并说明必要的 SDK 假设。
- 解析最终属性值后按此顺序分类:1) 最终 UseVSTest=true 选择 VSTest;若 global.json 同时选择原生 MTP 命令模式,报告 Platform: unavailable,因为命令模式与项目 opt-out 冲突。2) global.json 中的原生 MTP 选择会在最终 OutputType=Exe 时执行兼容的 MTP 应用;仅 VSTest、库输出或 opt-out 的项目为 unavailable。3) 在 SDK 8/9 上,启用的 MTP runner 加最终 TestingPlatformDotnetTestSupport=true 加最终 OutputType=Exe 在 MTP 上执行。4) 若 runner 启用但 bridge 缺失或为 false,双能力的 MSTest、NUnit 或 xUnit 项目仍留在 VSTest:runner 建立 MTP 能力,但 SDK 8/9 的 dotnet test 无法到达它,VSTest 适配器反而执行测试;若 bridge 为 true 但无 runner 启用,项目也留在 VSTest。5) runner 与 bridge 但输出不可执行则不完整且 unavailable;所选 SDK 路径无法到达的仅 MTP 框架也 unavailable,而非 VSTest。
- 保持每个信号角色精确:runner 属性选择测试应用;TestingPlatformDotnetTestSupport=true 让 SDK 8/9 的 dotnet test 到达该应用;OutputType=Exe 提供可执行宿主形态,它不选择也不启用 MTP。
- 不要混淆 MSTest 元包与 MSTest.Sdk 项目 SDK;PackageReference Include="MSTest" 加 EnableMSTestRunner=true 启用 MSTest MTP runner,但不隐式设置 TestingPlatformDotnetTestSupport。
- MSTest.Sdk 默认启用 MTP runner;检查其解析版本和求值属性以了解 bridge 行为:3.8 版提供 TestingPlatformDotnetTestSupport,除非更晚赋值覆盖;较新 SDK 在 .NET 10 上可能期望原生 MTP 模式;<UseVSTest>true</UseVSTest> 可 opt back 到 VSTest。
- 信号含义:<Project Sdk="MSTest.Sdk..."> 且无 UseVSTest 为 MTP 应用,需检查解析的 SDK 版本和求值的 bridge 属性;MSTest 元包 + <EnableMSTestRunner>true> 为 MTP runner 启用,不暗示 VSTest 到 MTP 的 bridge;<UseMicrosoftTestingPlatformRunner>true 为决定性的 xUnit runner 选择信号;<EnableMSTestRunner>true>/<EnableNUnitRunner>true> 为决定性的 MSTest/NUnit runner 选择信号;TestingPlatformDotnetTestSupport=true 是 VSTest 到 MTP bridge 的执行前置条件,不是 runner 选择信号;Microsoft.Testing.Platform 包为具备 MTP 能力的应用,本身不决定性;TUnit 为仅 MTP 框架;最终求值的 <OutputType>Exe</OutputType> 为基于包的 MTP 应用所需的可执行宿主形态。
- Microsoft.NET.Test.Sdk 单独不决定性;它可在启用 MTP 的项目中为兼容性保留;当显式覆盖决定结果时,指出最终覆盖及其来源,而非被取代的默认值;当 runner 选择属性与 Microsoft.NET.Test.Sdk 竞争时,说明 runner 属性选择 MTP 且 Microsoft.NET.Test.Sdk 不选择也不暗示 VSTest,它可作为兼容支持保留但属次要;TestingPlatformDotnetTestSupport=true 是 bridge 前置条件,不是 runner 选择信号,绝不要说该属性单独启用 bridge;对问单一决定信号的请求到此为止;配置完整时省略 bridge 或宿主形态前置条件,仅在需要解释所选 runner 为何无法执行时添加;同样,当启用的 runner 被覆盖或不可达时,因果地说明两个轴:runner 属性使项目具备 MTP 能力,但最终 UseVSTest/bridge/output 设置决定实际执行平台;先指出 runner 选择器,再仅用包引用识别框架。
- 使用因果证据而非一堆信号,例如:Platform: MTP / Framework: NUnit / Directory.Build.props 提供最终 EnableNUnitRunner=true 和 TestingPlatformDotnetTestSupport=true,因此 NUnit 在 MTP 上执行。
- 对不兼容配置,在结论后给出一个最小对齐选择而不修改文件:要么全局选择项目已配置的平台,要么移除项目 opt-out 以使用全局选择的平台。
- 按目标框架求值 runner 和 bridge 属性;若条件产生不同执行平台,逐目标显式报告(例如 net8.0: VSTest、net9.0: MTP),而不是把项目归并为单一全局平台。
适用边界 · 注意事项
- 当用户要求运行/筛选测试、要命令、标志、TRX/dump 或测试命令/筛选错误时不要使用,应直接用 run-tests。
- 不要用于热重载或迁移。