As the WinRT API is laced with async methods, having a robust approach to testing async behavior is very helpful for producing a robust app. Here are a few keys suggestions.

First, test re-entering a page multiple times when that page starts async operations. That is, navigate to a page that starts those operations, navigate away, then navigate forward again. Repeat a few times. Ideally what’s happening in the code is that any unfinished async operation is canceled then you leave the page. Otherwise this test can produce redundant operations that could collide.

More generally, the suggestion above means to plan and test for cancelation. With this, look at behaviors in your UI that depend on async operations either being started or completing, such as enabling/disabling controls.

You can also insert random delays in your code for async calls. In JavaScript this would mean creating a promise with WinJS.Promise.timeout(<delay>) and adding that to your chain. In C#/VB, use await Task.Delay inside an #ifdef DEBUG.

In JavaScript, because we don’t have #ifdef and because a new promise inserted into a chain needs to deliver meaningful results from the previous step in the chain, a good approach is to create a function that has as its return value a function that can serve as a completed handler in the chain. For example, assume you have a chain like this:

operation1().then(function (result1) {
return operation2(result1)
}).then(function (result2) {
return operation3(result2);
}).done();
You can create a function like this to create a delaying completed handler, where the debugMode flag would be a global variable that determines whether to create a delay promise with the previous result in the chain, or just deliver it through WinJS.Promise.as which adds very minimal overhead:

function insertDelay(delay) {
return function (result) {
if (debugMode) {
return WinJS.Promise.timeout(delay).then(function () { return result; });
} else {
return WinJS.Promise.as(result);
}
}
}

Inserting into the chain would be like this:

operation1().then(function (result1) {
return operation2(result1)
}).then(insertDelay(1000))
.then(function (result2) {
return operation3(result2);
}).done();

 


One Trackback

  1. [...] Testing Tip #10: Testing async operations (Kraig Brockschmidt) [...]

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>