2013-01-18 74 views
0

當標有「異步」的測試用例失敗時,將出現問題。在這種情況下,應用程序正在崩潰,TargetInvocationFail出現未處理的異常。據我所知,測試應用程序應該處理這些例外,因爲在例外的情況下,它應該將相應的情況標記爲失敗。這正是正常測試用例(沒有異步/等待它的東西)發生的情況。在異步異常期間WPToolkitTestFx應用程序崩潰異步無效測試用例

我也爲此創建了一個問題報告,請參閱http://phone.codeplex.com/workitem/10751。如果您遇到同樣的問題,請提出問題。如果您碰巧知道一些解決方法,請在此告訴我。

編輯:正如Stephen Cleary在評論中提到的那樣,問題是由於我的測試用例過程是異步無效而不是異步任務。我將按如下方式重新構造這個問題:爲什麼改變測試用例的返回類型會改變異常處理的行爲?

+1

你沒有在這裏或在您的問題報告中發佈代碼。如果我要猜測,我會說當你的單元測試方法應該是'async Task'時,你的單元測試方法是'async void'。 –

+0

你沒有問過任何問題。你是否有一個? – svick

+0

@StephenCleary你是絕對正確的,使東西異步任務而不是異步無效修復此問題。請允許我虛心地問你回答爲什麼會發生這種情況?我將用這個信息編輯問題。 – Haspemulator

回答

3

一個很好的通用指南是「避免async void」。其中一個原因是異常處理方面的差異:async Task方法將在返回的Task上放置任何例外,當Taskawait時,可以觀察到這些例外。 async void方法將直接在async void方法開始時的SynchronizationContext上提出異常。

要記住的另一件事是async主要是一個編譯器轉換。如果您(或其他人)在運行時反映了async Task方法,則只會看到返回類型爲Task的方法;同樣,async void方法的返回類型只有void

所以,當測試跑步看到返回void的方法(不知道它是一個async void方法),它執行它,看到它返回不(直接)拋出一個異常,所以它標記爲「通過」。同時,async void方法拋出的異常直接在SynchronizationContext上提出(大多數測試運行程序,包括MSTest,提供線程池SynchronizationContext),並且此異常可能會導致測試運行報告非特定錯誤 - 或者可能可能如果測試運行足夠快,則會被忽略。

現代測試跑步者(包括MSTest的作爲VS2012的)理解async Task方法通過檢測Task返回類型,以及將等待Task到考慮到測試方法「已完成」,並將其標記爲合格(或失敗之前完成,如果返回的Task包含例外)。

我有examples of this behavior in MSTest on my blog(包括顯示競賽條件的兩種輸出的截圖),但請注意,這些博客條目已近乎一年的時間,並與VS2010談論了async單元測試。 MSTest已更新爲VS2012,因此它對async Task方法具有合理的行爲。

0

我們在SL/WP工具包崩潰時遇到的主要問題是在測試失敗或調用TestComplete兩次後斷言或調用TestComplete引起的。 示例:假設您使用超時屬性標記測試,並且您正在等待比超時時間更長的網絡請求。如果webrequest沒有失敗,但速度很慢,在單元測試框架認爲完成之後,它仍然會返回並調用TestComplete()。我不知道測試測試是否超時的方法,因此我可以編寫測試來防範這種情況,所以我建議不要在某些情況下使用它。

另一種情況是您等待兩個事件,例如「已完成」和「失敗」事件,如果其中一個事件發生,您做了不同的事情,但它們都調用TestComplete:假設您的代碼意外引發兩個事件=>您只是稱測試完成,代碼失敗。 第三種情況是你有一個共享對象,比方說一個WebClient實例,你不會在每個測試中重新創建:現在,第一個測試用於偵聽DownloadString,並完成它。下一次測試也會在運行時開始監聽DownloadString,但由於舊的測試並未從中解除綁定,因此DownloadStringCompleted事件處理程序將再次運行,從而導致單元測試崩潰。

正如Stephen提到的,你不能在SL和WP單元測試框架中返回任務。我已經設法將其轉換成Silverlight單元測試運行器,您可以在這裏閱讀:http://www.sharpgis.net/post/2012/12/21/Hacking-the-Silverlight-Unit-Tests-to-support-returning-Task.aspx 我也很想爲Windows Phone單元測試做這件事,但是源代碼不可用,但請去投票,這個發佈在這裏:http://phone.codeplex.com/workitem/10642

也請投票支持增加了對工作支持的單元測試框架的位置: http://phone.codeplex.com/workitem/10727(WinPhone)這裏: http://silverlight.codeplex.com/workitem/11457(Silverlight的)