【问题标题】:Some unit tests runs indefinitely一些单元测试无限期运行
【发布时间】:2021-08-06 19:29:10
【问题描述】:

在一个解决方案中,我将 600 个单元测试拆分到不同的库中,其中 450 个存在于单个库中。使用 Visual Studio(最新版本)在我的计算机上运行该特定库的测试时,一切顺利。但是,在我们的构建服务器上,某些测试使用 dotnet.exe 测试命令永远不会结束。

dotnet.exe test C:\agent\_work\137\s\tests\XXX.Commercial.Infrastructure.Tests\XXX.Commercial.Infrastructure.Tests.csproj --logger trx --results-directory C:\agent\_work\_temp --configuration release -l "console;verbosity=detailed"

我在本地计算机上测试了该命令,一切顺利。我直接在我们的构建服务器上使用 Visual Studio 执行了测试,我可以在 Visual Studio 上重现这个问题。我必须取消那些永无止境的,然后再次运行它们以使它们成功。

Image of the Test Explorer on my local desktop

Image of the Test Explorer on the build server (test never end)

Image of Azure DevOps output after waiting 10 minutes after the last test and cancellation

出现问题的测试库的 .csproj

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <IsPackable>false</IsPackable>
        <ProjectGuid>{7BFDD481-8C96-41BD-9B8E-B7E1ECE9A6AC}</ProjectGuid>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="AutoFixture.AutoMoq" Version="4.11.0" />
        <PackageReference Include="AutoFixture.Xunit2" Version="4.11.0" />
        <PackageReference Include="coverlet.collector" Version="3.0.2">
            <PrivateAssets>all</PrivateAssets>
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="coverlet.msbuild" Version="3.0.2">
            <PrivateAssets>all</PrivateAssets>
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="FluentAssertions" Version="5.10.3" />
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
        <PackageReference Include="Moq" Version="4.16.0" />
        <PackageReference Include="xunit" Version="2.4.1" />
        <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
            <PrivateAssets>all</PrivateAssets>
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
    </ItemGroup>

在互联网上,我找到了这个,但它不相关/不能解决我的问题:

https://github.com/microsoft/vstest/issues/224

https://github.com/xunit/xunit/issues/1910

编辑

这是一个阻止示例的单元测试:

[Fact]
public async Task SendSuccessReservationEmailConfirmationTest()
{
    Reservation reservation;
    using (var merchantContext = this._merchantContextFactory.Invoke())
    using (var reservationContext = this._reservationContextFactory.Invoke())
    {
        var merchant = await merchantContext.Merchants.FirstOrDefaultAsync();
        reservation = await reservationContext.Reservations
            .FirstOrDefaultAsync(x => x.MerchantId.Equals(merchant.Id));

        Assert.NotNull(reservation);
        Assert.NotNull(merchant);

        reservation.MerchantId = merchant.Id;
        reservationContext.SaveChanges();
    }

    await this._reservationNotificationService.SendReservationConfirmationAsync(reservation.Id);
}

编辑 2

Visual Studio:16.9.5

DotNet CLI:5.0.203

有什么想法吗?谢谢你的帮助

【问题讨论】:

  • 相同的单元测试失败还是随机的?
  • 看起来它们是无限期运行的相同测试。我分析了它们,它们并没有什么共同点([Fact]、[Theory]、有/无 [InlineData]、[AutoMoqData] 等),但这很有趣。按顺序运行它们可以工作。现在我有一个临时解决方案。感谢stackoverflow.com/a/38558004/9563913
  • 它们是否涉及异步工作?
  • 是的,所有这些,在不同的点上。调用被测方法时,调用创建SUT的方法,或者进行方法封装。
  • 您可能在某处遇到了死锁情况。他们可能会锁定相同的资源。你能发布一些永无止境的测试吗?

标签: .net unit-testing .net-core azure-devops xunit


【解决方案1】:

我终于找到了问题。

使用 Visual Studio 的“Parallel Stacks”工具(调试 -> Windows -> Parallel Stacks),我能够找到发生死锁的类/方法。

调用此方法的多个测试:

/// <summary>
/// Builds this instance and starts the bus.
/// </summary>
/// <returns></returns>
public async Task<MassTransitHelper> BuildAsync()
{
    var bus = Bus.Factory.CreateUsingInMemory(configure =>
    {
        foreach (var (queue, configurator) in this._endpointConfigurators)
        {
            configure.ReceiveEndpoint(queue, configurator);
        }
    });

    await bus.StartAsync();

    return new MassTransitHelper(bus, new MessageBrokerSettings
    {
        MessageBrokerHostAddress = "loopback://localhost:5672/",
        MessageBrokerPassword = "guest",
        MessageBrokerUserName = "guest"
    });
}

但是,服务的多个单元测试使用“.Result()”而不是 await 调用此方法,它们都是同步测试。通过使它们异步并删除“.Result()”来解决此问题。

感谢大家的帮助。

【讨论】:

  • 嗨@TimothéePalumbo,感谢您分享您的经验。我建议您可以将您的答案标记为该主题的解决方案。这对于正在寻找类似问题的解决方案的其他人可能非常有帮助。谢谢。
  • 嗨@BrightRan-MSFT。是的,抱歉耽搁了,我需要等 1 天,但我忘了:-)。谢谢提醒
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 2011-11-18
  • 2016-10-07
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多