[英]Running xUnit tests on Teamcity using async methods
我做了以下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首先沒有正確運行測試? 有解決方案可以解決這個問題嗎?
任何人都可以向我解釋為什么在teamcity buildserver上運行的xUnit首先沒有正確運行測試?
首先,我會檢查你的xUnit版本 - 你應該運行最近發布的2.0版本。 我懷疑你的本地版本可能已經過時了。
核心問題在於這一行:
var resultString = response.Content.ReadAsAsync<string>().Result;
我懷疑你遇到了我在博客上描述的僵局 。 HttpClient
在某些平台上有一些方法沒有正確使用ConfigureAwait(false)
,因此會遇到此死鎖。 xUnit 2.0將單線程SynchronizationContext
安裝到其所有單元測試中,這提供了另一半的死鎖方案。
正確的解決方案是使用await
替換Result
,並將單元測試方法的返回類型從void
更改為Task
。
你的測試破了。
xUnit需要Task
返回才能確定測試失敗並且更重要的是,它是異常氣泡回到xUnit的句柄。
通過使public async void
,您有一個異常的孤立Task
。 由此產生的例外當然沒有得到處理,因此當然會炸毀整個過程。 因此,您的測試運行停止。
您可以通過編寫所有類似的測試來修復它...
[Fact]
public async Task 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!");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.