Live Unit Testing 常见问题解答

支持的框架

Live Unit Testing 支持哪些测试框架以及支持的最低版本是什么?

Live Unit Testing 适用于下表中列出的三种常用单元测试框架。 表中还列出了其适配器和框架的最低支持版本。 单元测试框架可从 NuGet.org 获取。

测试框架 Visual Studio 适配器最低版本 框架最低版本
xUnit.net xunit.runner.visualstudio 版本 2.2.0-beta3-build1187 xunit 1.9.2
NUnit NUnit3TestAdapter 版本 3.7.0 NUnit 版本 3.5.0
MSTest MSTest.TestAdapter 1.1.4-preview MSTest.TestFramework 1.0.5-preview

如果具有引用 Microsoft.VisualStudio.QualityTools.UnitTestFramework 且不希望移动到较新的 MSTest NuGet 包的基于 MSTest 的测试项目,请升级到 Visual Studio 2019 或 Visual Studio 2017。

.NET Core 支持

Live Unit Testing 是否适用于 .NET Core?

是的。 Live Unit Testing 适用于 .NET Core 和 .NET Framework。

配置

为什么在打开 Live Unit Testing 时无法正常工作?

“输出”窗口(选择“Live Unit Testing”下拉列表时)应告知你为什么 Live Unit Testing 不起作用。 Live Unit Testing 可能由于以下原因之一而不起作用:

  • 如果解决方案中项目引用的 NuGet 包尚未还原,则 Live Unit Testing 将不起作用。 在启用 Live Unit Testing 之前,执行解决方案的显式生成或还原解决方案中的 NuGet 包应解决此问题。

  • 如果在项目中使用基于 MSTest 的测试,请确保删除对 Microsoft.VisualStudio.QualityTools.UnitTestFramework的引用,并添加对最新 MSTest NuGet 包的引用,MSTest.TestAdapter(至少需要 1.1.11 版)和 MSTest.TestFramework(最低版本为 1.1.11)。 有关详细信息,请参阅 Visual Studio 文章中 使用 Live Unit Testing 的“支持的测试框架”部分。

  • 解决方案中的至少一个项目应具有 NuGet 引用或直接引用 xUnit、NUnit 或 MSTest 测试框架。 此项目还应引用相应的 Visual Studio 测试适配器 NuGet 包。

为什么我的项目未生成?

选择“实时单元测试”下拉列表时,生成错误将报告给“输出”窗口。 安装向导中的配置不正确导致几个常见问题 可能导致 Live Unit Testing 中的生成问题。

  • 如果 工作区根 属性太长,则生成可能会由于指示路径太长而失败。

  • 如果 存储库根 属性不指向存储库根目录,则工作区将填充错误的文件集。

  • 对于 git 存储库,排除文件 属性通常避免复制 gitignore 文件中指定的文件。 但是,可以将文件签入到忽略的 git 存储库,或者可以运行自动生成文件的工具,但在生成过程中不会生成这些文件。 在这些情况下,应选择“<自定义>”选项,并选择一组仅列出项目文件夹的规则。

除了前面所述的问题之外,可能无法正确生成的以下项目配置。

  • 如果项目依赖项被指定为全局解决方案配置,而不是每个项目的 ProjectReferences,Live Unit Testing 最终可能会生成不正确的项目集。 若要解决此问题,请在项目之间添加显式引用。

  • 在选择 Live Unit Testing 播放列表 之前,Live Unit Testing 不会生成任何项目。 若要解决此问题,请在 Live Unit Testing 播放列表中包含一些测试。

  • 如果在项目中使用基于 MSTest 的测试,请确保删除对 Microsoft.VisualStudio.QualityTools.UnitTestFramework的引用,并添加对最新 MSTest NuGet 包的引用,MSTest.TestAdapter(至少需要 1.1.11 版)和 MSTest.TestFramework(最低版本为 1.1.11)。 有关详细信息,请参阅 支持的测试框架

  • 解决方案中的至少一个项目应具有 NuGet 引用或直接引用 xUnit、NUnit 或 MSTest 测试框架。 此项目还应引用相应的 Visual Studio 测试适配器 NuGet 包。 还可以通过 .runsettings 文件引用 Visual Studio 测试适配器。 .runsettings 文件必须具有如下例所示的条目:

<RunSettings>
    <RunConfiguration>
          <TestAdaptersPaths>path-to-your-test-adapter</TestAdaptersPaths>
    </RunConfiguration>
</RunSettings>

Live Unit Testing 是否支持源生成器项目?

Live Unit Testing 无法使用检测生成源生成器项目。 由于 C# 编译器如何为源生成器设置程序集加载,因此尝试生成具有检测的源生成器项目无法加载 Live Unit Testing 程序集。

可以在源生成器 csproj 文件中设置 <ExcludeFromCodeCoverage>true</ExcludeFromCodeCoverage> 属性,以使这些项目在 Live Unit Testing 中生成。

如何解决错误“无法加载文件或程序集'Microsoft.Bcl.AsyncInterfaces'”?

由于性能原因,Live Unit Testing 在其自己的进程中运行生成。 如果此单独的生成进程导致错误,可以将 <UseInProcMSBuildNode>false</UseInProcMSBuildNode> 设置为 .lutconfig 文件,以确保所有生成都在 MSBuild 进程中发生。

为什么我的测试无法运行?

  • 一个常见问题是,并非所有文件都复制到测试文件夹。 可能需要向 csproj 文件添加一些 Live Unit Testing 测试依赖项 项。

  • 另一个问题是超时。 由于 Live Unit Testing 无限期运行测试,因此如果测试运行时间过长,它会自动中止运行。 可以增加项目的 向导中的超时时间。

升级后的覆盖率不正确

将 Visual Studio Projects 中引用的测试适配器升级到受支持的版本后,Live Unit Testing 为何显示不正确的覆盖范围?

  • 如果解决方案中的多个项目引用 NuGet 测试适配器包,则每个项目都必须升级到受支持的版本。

  • 请确保 MSBuild .props 从测试适配器包导入的文件也已正确更新。 检查导入的 NuGet 包版本/路径,通常可在项目文件的顶部附近找到,如下所示:

      <Import Project="..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props')" />
    

自定义生成

是否可以自定义 Live Unit Testing 版本?

如果解决方案需要为检测(Live Unit Testing)构建的自定义步骤,而“常规”非检测生成不需要,则可以将代码添加到项目或 .targets 文件,用于检查 BuildingForLiveUnitTesting 属性并执行自定义预生成步骤。 还可以选择删除某些生成步骤(如发布或生成包),或者根据此项目属性将生成步骤(如复制先决条件)添加到 Live Unit Testing 生成。 基于此属性自定义生成不会以任何方式更改常规生成,并且仅影响 Live Unit Testing 生成。

例如,可能有一个在常规生成期间生成 NuGet 包的目标。 你可能不希望在每次编辑后生成 NuGet 包。 因此,可以通过执行以下作在 Live Unit Testing 生成中禁用该目标:

<Target Name="GenerateNuGetPackages" BeforeTargets="AfterBuild" Condition="'$(BuildingForLiveUnitTesting)' != 'true'">
    <Exec Command='"$(MSBuildThisFileDirectory)..\tools\GenPac" '/>
</Target>

测试资源管理器与 Live Unit Testing

从测试资源管理器窗口运行测试与在 Live Unit Testing 中运行测试有何不同?

有几个区别:

  • 测试资源管理器运行或调试测试 窗口运行常规二进制文件,而 Live Unit Testing 则运行检测的二进制文件。 如果要调试检测的二进制文件,请在测试方法中添加 Debugger.Launch 方法调用会导致调试器在执行该方法时启动(包括 Live Unit Testing 执行该方法时),然后可以附加和调试检测的二进制文件。 但是,我们希望对于大多数用户方案,检测是透明的,并且不需要调试检测的二进制文件。

  • Live Unit Testing 不会创建新的应用程序域来运行测试,但测试从 测试资源管理器运行 窗口确实会创建新的应用程序域。

  • Live Unit Testing 按顺序在每个测试程序集中运行测试。 在 测试资源管理器中,可以选择并行运行多个测试。

  • 默认情况下,测试资源管理器 在单线程单元(STA)中运行测试,而 Live Unit Testing 在多线程单元(MTA)中运行测试。 若要在 Live Unit Testing 中的 STA 中运行 MSTest 测试,请使用可在 MSTest.STAExtensions 1.0.3-beta NuGet 包中找到的 <STATestMethod><STATestClass> 属性修饰测试方法或包含类。 对于 NUnit,使用 <RequiresThread(ApartmentState.STA)> 属性修饰测试方法,并使用 <STAFact> 属性修饰 xUnit。

排除测试

如何排除测试参与 Live Unit Testing?

有关用户特定的设置,请参阅 visual Studio 中的 使用 Live Unit Testing 的“包括和排除测试项目和测试方法”部分 一文。 如果要运行特定编辑会话的特定测试集或保留自己的个人首选项,包括或排除测试非常有用。

对于特定于解决方案的设置,可以通过编程方式应用 System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute 属性,以排除 Live Unit Testing 检测的方法、属性、类或结构。 此外,还可以将 <ExcludeFromCodeCoverage> 属性设置为在项目文件中 true,以排除要检测的整个项目。 Live Unit Testing 仍将运行尚未检测的测试,但其覆盖范围不会可视化。

还可以检查 Microsoft.CodeAnalysis.LiveUnitTesting.Runtime 是否已加载到当前应用程序域中,并根据原因禁用测试。 例如,可以使用 xUnit 执行如下作:

[ExcludeFromCodeCoverage]
public class SkipLiveFactAttribute : FactAttribute
{
   private static bool s_lutRuntimeLoaded = AppDomain.CurrentDomain.GetAssemblies().Any(a => a.GetName().Name ==
                                            "Microsoft.CodeAnalysis.LiveUnitTesting.Runtime");
   public override string Skip => s_lutRuntimeLoaded ? "Test excluded from Live Unit Testing" : "";
}

public class Class1
{
   [SkipLiveFact]
   public void F()
   {
      Assert.True(true);
   }
}

连续生成

即使我未进行任何编辑,Live Unit 测试仍会一直持续生成解决方案?

即使生成过程生成了属于解决方案本身的源代码,并且生成目标文件没有指定的适当输入和输出,你的解决方案也可以生成。 应为目标提供输入和输出列表,以便 MSBuild 可以执行适当的 up-to日期检查并确定是否需要新生成。

每当实时单元测试检测到源文件已更改时,就会启动生成。 由于解决方案的生成会生成源文件,因此 Live Unit Testing 将进入无限生成循环。 但是,如果在 Live Unit Testing 启动第二个生成时检查目标的输入和输出(在检测上一个生成中新生成的源文件后),它将中断生成循环,因为输入和输出检查指示所有内容都 up-to-date。

编辑器图标

尽管 Live Unit Testing 似乎基于“输出”窗口中的消息运行测试,但我为什么在编辑器中看不到任何图标?

如果由于任何原因未检测 Live Unit Testing 运行的程序集,则可能无法在编辑器中看到图标。 例如,Live Unit Testing 与设置 <UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>的项目不兼容。 在这种情况下,需要更新生成过程以删除此设置,或将其更改为 true,以便 Live Unit Testing 正常工作。 

捕获日志

如何收集更详细的日志来提交 bug 报告?

可以执行多项作来收集更详细的日志:

  • 转到 工具>选项>Live Unit Testing,并将日志记录选项更改为 详细。 详细日志记录会导致 输出 窗口中显示更详细的日志。

  • LiveUnitTesting_BuildLog 用户环境变量设置为要用于捕获 MSBuild 日志的文件的名称。 然后,可以从该文件检索 Live Unit Testing 生成的详细 MSBuild 日志消息。

  • LiveUnitTesting_TestPlatformLog 用户环境变量设置为 1 以捕获测试平台日志。 然后,可以从 [Solution Root]\.vs\[Solution Name]\log\[VisualStudio Process ID]检索 Live Unit Testing 运行的详细测试平台日志消息。

  • 创建名为 VS_UTE_DIAGNOSTICS 的用户级环境变量,并将其设置为 1(或任何值),然后重启 Visual Studio。 现在,应在 Visual Studio 的“输出 - 测试”选项卡中看到大量日志记录。

工作区文件夹

是否可以编辑工作区文件夹下的文件?

否,不应在工作区文件夹的生成和测试目录下打开或编辑文件。 Live Unit Testing 应管理 src 文件夹中的所有文件,使其在 存储库根工作区根之间保持同步。

开发驱动器

实时单元测试是否支持默认工作区根目录的开发驱动器?

是的,但你需要确保它已启用。 如果使用开发驱动器,请确保已启用 投影文件系统(ProjFS) 筛选器。 例如,以下命令启用 ProjFS 和 Windows Defender:

fsutil devdrv setfiltersallowed PrjFlt,WdFilter

另请参阅