Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 5,970 | Comments: 44,492

filter by tags archive

Async tests in Silverlight


One of the things that we do is build a lot of stuff in Silverlight, usually, those things are either libraries or UI. Testing Silverlight was always a problem, but at least there is a solution OOTB for that.

Unfortunately, the moment that you start talking about async tests (for example, you want to run a web server to check things), you need to do things like this, EnqueueCallback, EnqueueConditional and other stuff that makes the test nearly impossible to read.

Luckily for us, Christopher Bennage stopped here for a while and created a solution.

It allows you to take the following sync test:

[Fact]
public void CanUpload()
{
    var ms = new MemoryStream();
    var streamWriter = new StreamWriter(ms);
    var expected = new string('a',1024);
    streamWriter.Write(expected);
    streamWriter.Flush();
    ms.Position = 0;

    var client = NewClient(); 
    client.UploadAsync("abc.txt", ms).Wait();

    var downloadString = webClient.DownloadString("/files/abc.txt");
    Assert.Equal(expected, downloadString);
}

And translate it to:

[Asynchronous]
public IEnumerable<Task> CanUpload()
{
    var ms = new MemoryStream();
    var streamWriter = new StreamWriter(ms);
    var expected = new string('a', 1024);
    streamWriter.Write(expected);
    streamWriter.Flush();
    ms.Position = 0;

    yield return client.UploadAsync("abc.txt", ms);

    var async = webClient.DownloadStringTaskAsync("/files/abc.txt");
    yield return async;

    Assert.AreEqual(expected, async.Result);
}

It makes things so much easier. To set this us, just reference the project and add the following in the App.xaml.cs file:

private void Application_Startup(object sender, StartupEventArgs e)
{
    UnitTestSystem.RegisterUnitTestProvider(new RavenCustomProvider());
    RootVisual = UnitTestSystem.CreateTestPage();
}

And you get tests that are now easy to write and run in Silverlight.


Comments

tobi

This technique is also useful pre C# 5 to get async code emulated using iterators.

José F. Romaniello

I like this thing, it is in fact how you implement co-routines. I guess in the near future with async/await in c# it is going to be simpler.

fact

Silverlight is dead

Harry Steinhilber

@fact Really? Last time I checked, Microsoft supports products for 10 years. In the next month or two, we are looking at the release of Silverlight 5. That means that Silverlight will be alive and kicking until at least the end of 2021.

Jeff Circeo

Thanks Ayende, this is definitely a much cleaner approach and I love it.

Coreo

Harry...

Silverligh IS dead, the technology like that was doomed at the very beginning. It is tedious, prone to errors, runs in a sandbox on the client machine, most corporations would never even allow it to be installed in their networks...Same as for Linq to SQL and other technologies, they just die. Stick to the ones that work. Now we are all bound to move the beaufully colored rectangles on the screen being thrilled that we use Metro....wow. But just for a few years, until Windows Phone finally dies... You wrote this in March this year, saying it is only a month of two until Silverlight 5, now we will soon be in 2012, so where is it? Get real.

lol
lol

No Coreo, he wrote it in December not in March. Get real.

K00lAid

Harry, dude just drink the Kool Aid, dont chug it.

Remco

@Coreo

March? How can he comment on a post which was not even published then.

Windows Phone dies? Wow, the only one who needs to get real is you. If you look at the world like this, just go sit in a hole somewhere where nobody can iritate you. And nobody is irritated by your useless statements.

my2c

Mouzik

And that is why everyone just needs to write dates yyyy-mm-dd :)

Harry Steinhilber

@Coreo, And which technologies that work should I stick to then? Maybe I should just continue to write Webforms apps? My point is that Silverlight will be supported for many years to come and there is no harm in continuing to use it.

As far as corporations not installing Silverlight, many actually do. And the fact that it is sandboxed on the client is a feature that corporations like from a security prospective.

As far as where is Silverlight 5, Microsoft released an RC in September, and it was unofficially supposed to RTM in November. However, the official site still shows a 2011 release timeframe. Is that real enough for you?

Peter

I need to express my feeling here in the comment thread, sorry, here goes:

Who cares if Silverlight dies. Who cares!

I guess it makes testing easier if it does?

Why do we care if Silverlight dies? Why do we care if Windows Phone dies?

It used to matter to me, but I don't understand why now. A lost time investment?

Marwijn

Hi All

I tried to use the same approach using microsoft async CTP to try to make the syntax a bit simpler. I came up with this:

[TestMethod] [Asynchronous] public async Task AnotherWay() { await SomeTestTask.DoSomethingAsync(); int result = await SomeTestTask.DoSomethingAsync();

await Delay(100);

Assert.AreEqual(42, result);

}

To make this working I added

public void ExecuteTest2(MethodInfo test) { Task task = (Task)test.Invoke(this, new object[] { });
EnqueueConditional(()=> task.IsCompleted || task.IsFaulted); EnqueueCallback(() => { if (task.IsFaulted) { throw task.Exception.InnerException; } }); EnqueueTestComplete(); } }

to AsynchronousTaskTest

and

if (Method.ReturnType == typeof(Task)) { var executer =
instance.GetType().GetMethod("ExecuteTest2"); executer.Invoke(instance, new[] { methodInfo }); }

to TestMethod.

Just let me know if it works for you.

Sam
Sam

I wish Silverlight was dead. It's a horrendous CPU hog even when it's (apparently) doing nothing, and it breaks expected UI conventions (context menus bug me the most). I'm pretty sure it's responsible for the random freezes the desktop at home is experiencing.

The only reason I haven't disabled it is Raven Studio and Azure Management Portal, and I dread having to start up either one of those.

Jimmy Zimms

And reading these comments I see that most everyone missed the entire point here that should be the take away. Regardless of underlying technology, if you are working in an intrinsically async environment (and that should be EVERYONE) then you have to deal with the realities of async APIs and the related tests for them. Oren points out real life techniques and components to handle this problem area in an elegant manner without getting in my way as a developer. Somehow people evolved into Silverlight is Dead vs Long Live Silverlight and missed the boat.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. RavenDB On Linux–Status Update - 6 hours from now

There are posts all the way to Jul 31, 2015

RECENT SERIES

  1. Production postmortem (5):
    29 Jul 2015 - The evil licensing code
  2. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
  3. API Design (7):
    20 Jul 2015 - We’ll let the users sort it out
  4. What is new in RavenDB 3.5 (3):
    15 Jul 2015 - Exploring data in the dark
  5. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats