I have a long running task method, using Sleep
public Task LongRunning() {
return Task.Factory.StartNew(
() => {
Trace.TraceInformation("Start Sleep");
Thread.Sleep(10000);
Trace.TraceInformation("End Sleep");
});
}
This is called by my test, and it works fine
[TestMethod]
public void SimpleContinueWith() {
Trace.TraceInformation("Start");
LongRunning()
.ContinueWith(
t => Trace.TraceInformation("End")
).Wait();
}
> QTAgent32.exe Information: 0 : Start
> QTAgent32.exe Information: 0 : Start Sleep
> QTAgent32.exe Information: 0 : End Sleep
> QTAgent32.exe Information: 0 : End
But using async/await the test falls straight through
[TestMethod]
public async void SimpleAwait() {
Trace.TraceInformation("Start");
await LongRunning();
Trace.TraceInformation("End");
}
> QTAgent32.exe Information: 0 : Start
> QTAgent32.exe Information: 0 : Start Sleep
Why is that then?
MSTest cannot (currently) handle asynchronous tests. I'm not sure if Microsoft is going to add this for the final release. Update: VS11 Beta did add support for async unit tests; see below.
You can unit test asynchronous methods by providing an async context yourself. There's some included in the Async CTP (Microsoft Visual Studio Async CTP\Samples\(C# Testing) Unit Testing\AsyncTestUtilities), or you can use one I wrote called AsyncContext.
Using AsyncContext
, your test can be written as:
[TestMethod]
public void SimpleAwait() {
AsyncContext.Run(async () =>
{
Trace.TraceInformation("Start");
await LongRunning();
Trace.TraceInformation("End");
});
}
Update, 2012-02-05: Another option is the new AsyncUnitTests library. Install that NuGet package, change your TestClass
to AsyncTestClass
, and your async unit tests can be written much more naturally:
[TestMethod]
public async void SimpleAwait() {
Trace.TraceInformation("Start");
await LongRunning();
Trace.TraceInformation("End");
}
Update, 2012-06-06: If you update to VS2012 Beta, you can define asynchronous unit tests; they just have to return Task
:
[TestMethod]
public async Task SimpleAwait() {
Trace.TraceInformation("Start");
await LongRunning();
Trace.TraceInformation("End");
}