使用异步方法在Teamcity上运行xUnit测试

时间:2015-08-14 08:45:10

标签: c# async-await xunit.net teamcity-9.0

我做了以下xUnit测试,该测试使用HttpClient在Web服务器上调用状态api方法。

[Fact]
public void AmIAliveTest()
{
    var server = TestServer.Create<Startup>();

    var httpClient = server.HttpClient;
    var response = httpClient.GetAsync("/api/status").Result;

    response.StatusCode.Should().Be(HttpStatusCode.OK);
    var resultString = response.Content.ReadAsAsync<string>().Result;

    resultString.Should().Be("I am alive!");
}

此测试在本地运行良好。但是当我提交代码并尝试在TeamCity构建服务器上运行相同的测试时,它会永远运行。我甚至不得不杀死xunit runner进程,因为停止构建不会停止这个过程。

然而,当我像这样编写测试时

[Fact]
public async void AmIAliveTest()
{
   var server = TestServer.Create<Startup>();

   var httpClient = server.HttpClient;
   var response = await httpClient.GetAsync("/api/status");

   response.StatusCode.Should().Be(HttpStatusCode.OK);
   var resultString = await response.Content.ReadAsAsync<string>();

   resultString.Should().Be("I am alive!");
}

它在本地和TeamCity上运行良好。

我现在担心的是,我忘了像第二个版本那样编写测试,并且偶尔会出现teamcity版本。

有人可以向我解释为什么在teamcity buildserver上运行的xUnit首先没有正确运行测试吗?有解决方案吗?

1 个答案:

答案 0 :(得分:7)

  

有人可以向我解释为什么在teamcity buildserver上运行的xUnit没有在第一时间正确运行测试吗?

首先,我会检查你的xUnit版本 - 你应该运行最近发布的2.0版本。我怀疑你的本地版本可能已经过时了。

核心问题在于这一行:

var resultString = response.Content.ReadAsAsync<string>().Result;

我怀疑你遇到了我在博客上描述的deadlock situationHttpClient在某些平台上有一些方法没有正确使用ConfigureAwait(false),因此会遇到此死锁。 xUnit 2.0在其所有单元测试中安装了一个单线程SynchronizationContext,它提供了另一半的死锁场景。

正确的解决方案是将Result替换为await,并将单元测试方法的返回类型从void更改为Task