Microsoft。Testing.Platform (MTP) 故障排除

本文包含 MTP 的故障排除指南。

退出代码

MTP 使用已知的退出代码来传达测试失败或应用错误。 退出代码从0开始且是非负数。

退出代码 详细信息
0 0退出代码指示成功。 所有选择的测试都成功完成,并且没有出现任何错误。
1 1 退出代码指示发生未知错误,并充当全部捕获。 若要查找其他错误信息和详细信息,请查看输出。
2 退出代码 2 用于指示至少有一个测试失败。
3 退出代码 3 指示测试会话已中止。 可以使用 Ctrl+C 中止会话,例如。
4 退出代码 4 指示已用扩展的设置无效,测试会话无法运行。
5 退出代码 5 指示传递给测试应用的命令行参数无效。
6 (不再使用) 退出代码 6 不再由平台生成;它之前指示测试会话正在使用未实现的功能。
7 退出代码 7 指示测试会话无法成功完成并可能崩溃。 这可能是由通过测试控制器扩展点运行的测试会话引起的。
8 退出代码 8 指示测试会话运行零测试。
9 退出代码 9 指示违反了已执行测试的最低执行策略。
10 退出代码 10 指示测试适配器 Testing.Platform Test Framework、MSTest、NUnit 或 xUnit 未能运行测试,因为基础结构原因与测试本身无关。 例如,无法创建测试所需的装置。
11 退出代码 11 指示如果依赖进程退出,测试进程将退出。
12 退出代码 12 指示测试会话无法运行,因为客户端不支持任何受支持的协议版本。
13 退出代码 13 指示由于使用 --maximum-failed-tests 命令行选项达到指定数目的最大失败测试,测试会话已停止。 有关详细信息,请参阅 MTP CLI 选项参考中的“选项”部分

若要启用详细日志记录并排查问题,请参阅 诊断日志记录

忽略特定退出代码

MTP 默认设计为严格,但允许配置。 因此,用户可以决定应忽略哪些退出代码(将返回退出代码 0 而不是原始退出代码)。

若要忽略特定的退出代码,请使用 --ignore-exit-code 命令行选项或 TESTINGPLATFORM_EXITCODE_IGNORE 环境变量。 接受的有效格式是要忽略的退出代码的分号分隔列表(例如,--ignore-exit-code 2;3;8)。 一种常见方案是,测试失败不应导致非零退出代码(这对应于忽略退出代码 2)。

诊断日志记录

该平台提供内置的诊断日志记录,可帮助你排查测试执行问题。 可以通过命令行选项或环境变量启用诊断日志记录。

命令行选项

以下 平台选项 提供了用于对测试应用进行故障排除的有用信息:

  • --info
  • --diagnostic
  • --diagnostic-synchronous-write
  • --diagnostic-verbosity
  • --diagnostic-file-prefix
  • --diagnostic-output-directory

环境变量

还可以使用环境变量启用诊断日志:

环境变量名称 Description
TESTINGPLATFORM_DIAGNOSTIC 如果设置为 1,则启用诊断日志记录。
TESTINGPLATFORM_DIAGNOSTIC_VERBOSITY 定义详细程度级别。 可用值包括 TraceDebugInformationWarningErrorCritical
TESTINGPLATFORM_DIAGNOSTIC_OUTPUT_DIRECTORY 诊断日志记录的输出目录,如果未指定,则会在默认的 TestResults 目录中生成该文件。
TESTINGPLATFORM_DIAGNOSTIC_FILE_PREFIX 日志文件名的前缀。 默认为 "log_"。 自 MTP 2.3.0 版本起可用;为保持向后兼容性,旧名称 TESTINGPLATFORM_DIAGNOSTIC_OUTPUT_FILEPREFIX 仍然受支持。
TESTINGPLATFORM_DIAGNOSTIC_SYNCHRONOUS_WRITE 强制内置的文件记录器以同步方式写入日志。 对于在进程崩溃时不想丢失任何日志条目的场景非常有用。 这会降低测试执行速度。 从版本 2.3.0 开始的 MTP 中可用;仍遵循旧名称 TESTINGPLATFORM_DIAGNOSTIC_FILELOGGER_SYNCHRONOUSWRITE 以实现向后兼容性。

注释

环境变量优先于命令行参数。

解决配置错误

Microsoft.Testing.Platform.MSBuild

下面是与 Microsoft.Testing.Platform.MSBuild 相关的常见配置错误。

错误 CS8892:由于找到了同步入口点“Program.Main(string[])”,因此不会将方法“TestingPlatformEntryPoint.Main(string[])”用作入口点。

在测试项目中手动定义入口点(Main),或者从已具有入口点的应用程序引用测试项目会导致与 MTP 生成的入口点冲突。 若要避免此问题,请执行以下步骤之一:

  • 删除手动定义的入口点,通常是 Main 中的 方法,让测试平台生成一个入口点。

  • 通过设置 <GenerateTestingPlatformEntryPoint>false</GenerateTestingPlatformEntryPoint> MSBuild 属性来禁用入口点的生成。

  • 通过在引用测试项目的项目中设置 Microsoft.Testing.Platform.MSBuild MSBuild 属性来完全禁用 <IsTestingPlatformApplication>false</IsTestingPlatformApplication> 的可传递依赖项。 从非测试项目引用测试项目(例如引用测试应用程序的控制台应用)时,需要这样做。

生成的代码命名空间与引用的类型冲突

Microsoft.Testing.Platform.MSBuild在项目的 SelfRegisteredExtensions 内生成 TestingPlatformEntryPoint$(RootNamespace) 类型。 默认情况下, RootNamespace 匹配项目名称,该项目名称可以与引用的程序集公开的同一完全限定名称的类型相冲突。

例如,一个名为 System.Security.Cryptography.ProtectedData.Tests 的项目最终会在 System.Security.Cryptography.ProtectedData 命名空间中生成代码。 如果项目还引用了 System.Security.Cryptography.ProtectedData NuGet 包,而该包在 System.Security.Cryptography 命名空间下包含一个公共 ProtectedData 类型,则编译器将无法再区分生成的命名空间和引用的类型,并会发出诸如 CS0118 之类的错误(“‘ProtectedData’是命名空间,却被当作类型使用”)。

若要解决该冲突,请在测试项目中将 RootNamespace 重写为一个不会与任何已引用类型发生冲突的值:

<PropertyGroup>
  <RootNamespace>System.Security.Cryptography.ProtectedDataTests</RootNamespace>
</PropertyGroup>

还可以完全清除 RootNamespace<RootNamespace />在这种情况下,生成的类型将发出到全局命名空间中)。

Microsoft.Testing.Extensions.Fakes

Fakes 错误。无法解析来自 COR_PROFILER_PATH 和 COR_PROFILER 环境变量的探查器路径

如果 Bin 文件夹中不存在所有 Fakes 程序集,则可能会出现此错误。

  • 请确保项目使用 MSTest.SDK 或引用 Microsoft.Testing.Extensions.Fakes
  • 对于 .NET Framework 项目,请避免设置 <PlatformTarget>AnyCPU</PlatformTarget>,因为这样 NuGet 不会将所有文件复制到 bin 文件夹。

混合测试框架或扩展的解决方案中无法识别的命令行选项

如果解决方案包含使用不同测试框架(例如 MSTest 和 xUnit.net)或不同扩展集的项目(例如,只有某些项目引用Microsoft.Testing.Extensions.HangDump),则运行具有特定于框架或特定于扩展的命令行选项的 dotnet test,退出代码 5 可能会失败。 该选项对一个项目有效,但另一个项目无法识别。

若要解决此问题,请使用具有条件的 TestingPlatformCommandLineArguments MSBuild 属性将参数路由到正确的项目。 有关详细说明,请参阅 包含混合测试框架或扩展的解决方案