The problem appears when test case marked with “async” is failing. App is just crashing in that case, with an unhandled exception of TargetInvocationFail. As far as I understand, the test app is supposed to handle those exceptions, because in case of exception it should just mark respective case as failed. This is exactly what happens with the normal test case (without async / await stuff in it).
I’ve created an issue report for this as well, see http://phone.codeplex.com/workitem/10751. If you have same problem, please upvote the issue. And if you happen to know some workaround, please let me know here.
EDIT: As Stephen Cleary mentioned in the comment, the issue was caused by the fact that my test case procedure was async void, not async Task. I’d reformulate this question as follows then: why changing return type of test case changes the behavior of the exception handling?
A good general guideline is “avoid
async void“. One reason for this is the difference in exception handling:async Taskmethods will place any exceptions on their returnedTask, which can be observed when thatTaskisawaited.async voidmethods will raise their exceptions directly on theSynchronizationContextthat was current at the time of the start of theasync voidmethod.Another thing to keep in mind is that
asyncis primarily a compiler transformation. If you (or anyone else) reflects over anasync Taskmethod at runtime, you’ll just see a method with a return type ofTask; similarly, anasync voidmethod just has a return type ofvoid.So, when the test runner sees a method returning
void(not knowing that it is anasync voidmethod), it executes it and sees it return without (directly) raising an exception, so it marks it as “passed”. Meanwhile, the exception thrown by thatasync voidmethod is raised directly on theSynchronizationContext(most test runners, including MSTest, provide a thread poolSynchronizationContext), and this exception can cause the test run to report a non-specific error – or it could possibly be ignored if the test run completes quickly enough.Modern test runners (including MSTest as of VS2012) understand
async Taskmethods by detecting the return type ofTask, and will wait for theTaskto complete before considering the test method “finished” and marking it as passed (or failed, if the returnedTaskcontains an exception).I have examples of this behavior in MSTest on my blog (including screenshots showing both outputs of the race condition), but note that those blog entries are almost a year old and talk about
asyncunit testing with VS2010. MSTest was updated with VS2012 so that it has reasonable behavior forasync Taskmethods.