Silverlight Unit Testing - adding a timeout to EnqueueConditional

Since a lot of Silverlight work is asynchronous in nature, the Silverlight testing framework has many helper functions to essentially do "non blocking wait until something happens"

The curious one to me is EnqueueConditional(Func<bool> conditionalDelegate

This one essentially waits until the condition is true - so you can call a method to populate your view model with data, and then wait until data.Count > 0

But the method has no support for timeout.  It can, and will, hold the unit testing framework in progress forever.

Here's my little tweak to the method.

        public override void EnqueueConditional(Func<bool> conditionalDelegate)
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 5);
            timer.Tick += delegate
            {
                // remember to stop timer or it'll tick again
                timer.Stop();
                throw new TimeoutException();
            };
            EnqueueCallback(delegate
            {
                timer.Start();
            });
            base.EnqueueConditional(conditionalDelegate);
            EnqueueCallback(delegate
            {
                timer.Stop();
            });
        }

Here's the unit test to go with it

        [TestMethod]
        [TestProperty("TestCategory", "Silverlight")]
        [Asynchronous]
        [ExpectedException(typeof(TimeoutException))]
        public void Test_Timeout()
        {
            EnqueueConditional(delegate
            {
                // return?  never!
                return false;
            });

            EnqueueTestComplete();
        }

And one more tweak in the App.xaml.cs

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is TimeoutException)
            {
                e.Handled = true;
                // stop any timeoutexception here or it'll bubble to the DOM
                return;
            }

            ...
        }

Here's the result picture:  Running just slightly over 5 seconds.

image

 

Updated: added a result picture.

Silverlight first asynchronous test run twice

I'm observing a pretty odd behaviour - the first test of my MVVM is running twice.

Exhibit Original code:

 
    [TestMethod, Asynchronous]
public void VMConnectTest() { ViewModel clientVM = CreateVM(); #region connect clientVM.Connect.Execute(null); base.EnqueueConditional(delegate { return clientVM.IsConnected; }); #endregion base.EnqueueTestComplete(); }

I have a break point in CreateVM - and it's firing twice, off the same line.

Changing the code to:

    [TestMethod, Asynchronous] 
public void VMConnectTest() { ViewModel clientVM = null; #region connect base.EnqueueCallback(delegate { clientVM = CreateVM() clientVM.Connect.Execute(null); }); base.EnqueueConditional(delegate { return clientVM.IsConnected; }); #endregion base.EnqueueTestComplete(); }

And now the CreateVM only runs once.

I suspect the Asynchronous test has a bug regarding mixing which thread is suppose to be creating the VM.  In this case, it's running twice.  Throwing everything onto the test stack seems to have fixed this, but makes the code look more complex than usual.

Silverlight Unit Testing Framework - modify/remove Tag Expressions dialog

The default Silverlight Unit Testing framework project has a lovely Tag Expressions welcome dialog that lets you decide (within 5 seconds), whether you want to run a subset.

How do you get rid of it?

image

 

Turns out it's pretty easy:

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            UnitTestSettings settings = UnitTestSystem.CreateDefaultSettings();
            settings.StartRunImmediately = true;
            settings.ShowTagExpressionEditor = false;

            RootVisual = UnitTestSystem.CreateTestPage(settings);
        }

Use UnitTestSystem.CreateDefaultSettings() to get you started quickly, if you create your own UnitTestSettings class you will have to set up your own Test Harness or you'll face this Exception:

 

Test harness was not specified on test harness settings object. If a test harness settings object was passed in, please verify that it contains a reference to a test harness.

C# Anonymous Delegate Syntax

In the effort to save key strokes, sometimes I wonder if C# code is becoming a bit unreadable.

Exhibit Original:

private void VMIsConnected() {
    Assert.IsTrue(vm.IsConnected);
}

...
EnqueueCallback(this.VMIsConnected);

 

Exhibit A:

EnqueueCallback( delegate {
    Assert.IsTrue(vm.IsConnected);
} );

 

Exhibit B:

EnqueueCallback( () => Assert.IsTrue(vm.IsConnected );

 

Which one do you use?

I like A.  Simple enough without extra function signature, yet readable.  The ( ) in Exhibit B scares me.

Windows Live Photo Gallery (beta)

The nastiest part of the whole Windows Live Wave 4 Beta experience so far has been concentrated on the installer - though not all Microsoft's fault, I did have some dodgy settings in my Internet Options.

Today, I flicked open the new Windows Live Photo Gallery, and this is a really nice application.

THE GOOD

  1. Automatically detected iPhone and offer to import pictures
    image
  2. Import offers to just grab everything, or group (and mass-tag) pictures based on the time they were taken.  Aka "afternoon trip", "evening dinner @ rocks"
    image
  3. Default view sorted pictures by Month
  4. Automatically detected the picture orientation and rotated them around.  Unlike…  a certain other company's software.  /blog/2010/4/15/apple-iphone-drivers-are-pos.html


    iPhone crap drivers.

    image
    Windows Live Photo Gallery import (automatically fixed orientation)
  5. Lovely Ribbons interface

THE AWESOME

  1. Panoramic photo stitching!IMG_3067 Stitch

    Long Zheng has a much better comparison
  2. Mass tagging, mass image adjustments
  3. Mass upload to Skydrive, Flickr or Facebook
  4. Extensible (this will make it even more awesome)