NuGet CPM 迁移后测试项目缺少 PackageReference,正常吗?
结论
仅在 Directory.Packages.props 中声明 <PackageVersion>,不足以让测试项目引用 Microsoft.NET.Test.Sdk。CPM 的常规做法是集中声明版本,再通过项目中的 <PackageReference Include="…" /> 声明依赖。NuGet CPM 文档
如果 .csproj 中没有看到引用,仍需检查共享配置或所用 SDK 是否已经添加了它。查明实际来源后,再决定是否补充。现有材料也不足以判断 CentralisedPackageConverter 删除该条目是否符合其具体版本的转换规则。
原配置中的 Update 是关键
迁移前的配置是:
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.14.1" />
Update 用于修改已有 MSBuild item 的元数据,不会创建新的引用。如果该语句求值时没有匹配的 PackageReference,它就不会添加依赖。因此,原配置本身不能证明该包由 SampleTest.csproj 引入。MSBuild item 文档
可能是共享配置此前已经添加了引用,这一行只修改版本;也可能是这一行原本就没有匹配到引用。需要检查完整导入链才能确定。
依赖可能来自哪里?
优先检查以下位置:
Directory.Build.props、Directory.Build.targets和其他导入的.props、.targets文件中,是否声明了PackageReference Include="Microsoft.NET.Test.Sdk"。- 所用测试 SDK 是否自动添加了相关依赖。
Directory.Packages.props是否还包含GlobalPackageReference。它与普通PackageVersion不同,可以向适用项目添加全局包引用。全局包引用说明- 其他 NuGet 包是否通过依赖关系引入了它。传递依赖可以解释包为何出现,但包的存在本身不能证明测试所需的构建资产已正确生效。PackageReference 资产规则
这些来源都需要结合当前项目验证,暂时无法认定具体原因。
如何确认实际引用来源?
1. 重新还原并查看包列表
在项目所在目录执行:
dotnet restore SampleTest.csproj
dotnet list SampleTest.csproj package --include-transitive
查看 Microsoft.NET.Test.Sdk 是否出现,以及它被列为顶层包还是传递包。使用 .NET 10 SDK 时,也可以使用以下命令:包列表命令文档
dotnet package list --project SampleTest.csproj --include-transitive
如果 SDK 为 .NET 8.0.4xx 或更高版本,还可以查看具体依赖链:dotnet nuget why 文档
dotnet nuget why SampleTest.csproj Microsoft.NET.Test.Sdk
2. 检查 MSBuild 导入与求值结果
生成展开导入后的项目文件:
dotnet msbuild SampleTest.csproj -pp:expanded.xml
在 expanded.xml 中搜索 Microsoft.NET.Test.Sdk,结合导入边界和条件查找声明来源。该文件展示导入内容,其中的条件分支并不一定都已生效。
若所用 MSBuild 支持 -getItem,可以进一步查看求值后的引用项:
dotnet msbuild SampleTest.csproj -getItem:PackageReference
这两个参数分别用于展开导入和查看求值结果。MSBuild 命令行文档
排查时应使用与 CI 一致的配置和目标框架,避免条件引用造成差异。
3. 确认该项目的测试确实执行
解决方案构建成功只能证明构建通过;即使 CI 成功,也需要结合 SampleTest 项目的测试报告判断。检查该项目的发现数、执行数、跳过数和结果,确认没有遗漏整个项目。
如果使用 VSTest,可以单独检查:
dotnet test SampleTest.csproj --list-tests
dotnet test SampleTest.csproj --logger trx
以上参数适用于 VSTest;Microsoft.Testing.Platform 的命令选项应按对应运行方式确认。VSTest 命令文档
是否应该手动补回引用?
如果这是使用 VSTest 的常规 SDK 风格测试项目,且没有共享配置或测试 SDK 为它添加有效引用,建议补充以下配置。Microsoft.NET.Test.Sdk 为这类项目提供运行测试所需的测试平台支持。VSTest 项目说明
在现有 Directory.Packages.props 中保留版本声明,并确认已启用 CPM:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
</ItemGroup>
</Project>
在 SampleTest.csproj 的现有 <Project> 内添加:
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
</ItemGroup>
CPM 下无需在这个 PackageReference 上重复填写 Version。
如果求值结果已经包含共享配置提供的引用,就不必再次添加同名 Include。若仅依赖其他包间接引入,则需要考虑上游包升级后依赖发生变化的风险。
如果项目使用 Microsoft.Testing.Platform,应根据所用测试框架和 SDK 的要求判断。它与 VSTest 的运行方式存在区别,不能直接套用 VSTest 的依赖配置。测试平台迁移说明
完成调整后,在干净工作目录中重新还原并单独运行该测试项目,核对测试结果,确认配置是否有效。
备注:内容仅供参考。
