Making sure asynchronous unit tests don’t cause a deadlock

In my previous blog post I wrote about creating asynchronous unit tests for Silverlight using the Microsoft Silverlight Unit Test Framework. This asynchronous testing capability that the Microsoft Silverlight Unit Test Framework has in the box lets us create some pretty advanced testing capabilities.

The problem with asynchronous tests.

While the async test pattern is very powerful it also has a drawback. This drawback is that the EnqueueTestComplete() must be executed or the test will never complete and the whole test run will halt. And while the test runner will tell you which test is executing it will not tell you where it is waiting, all it does is just sit there and wait.

Take the following test for example. Because the EnqueueConditional() action always returns false it is never going to end.

[TestMethod]
[Asynchronous]
public void TestThatNeverFinishes()
{
    // Do some asynchronous work

    EnqueueConditional(() => false);
    EnqueueTestComplete();
}


Now a Timeout attribute telling the Microsoft Silverlight Unit Test Framework to abort the test if it takes longer than a predefined amount of time would be nice. In fact there is even a Timeout attribute as part of the Microsoft.VisualStudio.TestTools.UnitTesting namespace but adding the Timeout attribute to a SilverlightTest has no effect [:(]



The solution



The solution is not very difficult but it does mean having to check for the timeout ourselves. In fact just adding an Assert to every EnqueueConditional() to make sure we don’t timeout will do the trick just fine. The only downside is that we have to do so in very check. If we change the test to the following the test will timeout, with an error, if it takes to long.



[TestMethod]
[Asynchronous]
public void TestThatNeverFinishes()
{
    DateTime startTime = DateTime.Now;

    // Do some asynchronous work

    EnqueueConditional(() =>
    {
        Assert.IsTrue((DateTime.Now - startTime) < TimeSpan.FromSeconds(10), 
            "Timeout on condition 'return false;'");
        return false;
    });

    EnqueueTestComplete();
}


The result is a “nice” error indicating the test took too long.



image



 



Nice, now if only the Microsoft Silverlight Unit Test Framework would support the Timeout attribute it would be even better.



Enjoy!



[f1]
[f2]

6 thoughts on “Making sure asynchronous unit tests don’t cause a deadlock

  1. I’m new to the site and just purchased lots of items last night, and still have not received an email with the items.

    How long does it normally take to get the items? I understood that as soon as I paid everything would be emailed

    to me. Just wondering……
    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>