This post will walk you through setting up a Unit Test Project for your Silverlight Application. It took me a day to successfully set everything up and make it working on a Team Foundation Build Server. The Silverlight Unit Test Framework is already out some years (starting from Silverlight 2) but with every new framework it is good to wait for some maturity. I will blog about the Unit Testing framework as it is now in Silverlight 4.
Prerequisites:
- Silverlight 4 Toolkit (April 2010) (includes Silverlight Unit Testing source)
Setup your Unit Test Silverlight Application
After installing the Silverlight Toolkit, you should have a Silverlight Unit Test Project available. The following screens will walk you through the setup.
Unit Testing your XAML Bindings
As we all use MVVM in our Silverlight applications these days… Make sure it doesn’t break any of the bindings.
Reasons that I could think of to test your XAML bindings.
- Typographical error in your XAML
- Make sure you don’t miss the silent tracing error of your binding mistake
- Your object property name changes
- Designers might mess with your bindings
First approach (howto test XAML bindings??)
There is a post by Jeremy Likeness that deals with testing your XAML bindings. The post was quite good and you get the idea but the code didn’t work very well for me.
Second and working approach.
The following code works for me and has a completely different approach. Silverlight Unit Testing has a number of methods to support the behaviour we are trying to test.
[Asynchronous]
[TestMethod]
[Tag("WorkflowDefinitionBindingIsValid")]
public void WorkflowDefinitionBindingIsValid()
{
EnqueueDelay(10);
// Internal Property Available using Assembly InternalsVisibleTo on Silverlight Project
var cbBooksCombobox = _booksView.cbBooksCombobox;
EnqueueCallback(() => { _booksViewModel.Books = _books; });
EnqueueCallback(() => CollectionAssert.AreEquivalent(cbBooksCombobox.Items, _books,
"Failed to data-bind books."));
EnqueueTestComplete();
}
Explanation:
- The Asynchronous Attribute is very important for these kind of tests. We want to allow the bindings to update before we continue further test execution.
- Enqueue methods
- EnqueueTestComplete() – This method indicates that your test is complete.
- EnqueueCallback() – This method will add a callback to your test method.
- EnqueueConditional() – Continue testing after the condition is met.
- EnqueueDelay() – Add a delay before continuing to evaluate work items.
- EnqueueWorkItem – This adds a task to the task queue.
- Getting access to the internal properties of your viewModel
[assembly: InternalsVisibleTo("org.vanderbiest.UnitTests")]
- Tagging your tests
You can tag your class and also tag your methods. I find it handy to tag both so you can test individual methods or just test your entire fixture class.
As you can see in the Sample Screenshot, I have placed my own Favorite Tags in the list. To achieve that, you will add the following code to the App.xaml.cs Startup event.
private void Application_Startup(object sender, StartupEventArgs e)
{
var settings = UnitTestSystem.CreateDefaultSettings();
settings.SampleTags.Clear();
settings.SampleTags.Add("BaseViewModelFixture");
settings.SampleTags.Add("BookListViewModelFixture");
settings.SampleTags.Add("MusicListViewModelFixture");
RootVisual = UnitTestSystem.CreateTestPage(settings);
}
Third approach: EnqueueConditional method
You might also want to check the following approach:
[TimeOut(200)]
[TestMethod]
[Asynchronous]
public void Test2()
{
int pageCount = 0;
FlickrRequest request = new FlickrRequest(typeof(MockTestableWebClient));
request.PhotoSearchByUser("97044050@N00", (photo) => pageCount++);
EnqueueConditional(() =>
{
return pageCount == 5;
});
EnqueueTestComplete();
}
This code will wait for a certain condition to be completed. Notice the TimeOut attribute to make sure you don’t fall into an endless loop…
The EnqueueCondition becomes handy when you want to test real time WCF calls.
Automating your Silveright Unit Tests at Build Server
StatLight
Differences in StatLight Visual Studio Debug - No Error Logging in TestInitialize
If something goes wrong in your Test Initialization you won’t get a good error description in StatLight. This is because of the Silverlight Test Framework not throwing any exceptions in your Test Initialization. Of course we don’t have any problems with it as long as we can debug our code but with StatLight, things are a bit different. It is recommended that you have a Smoke test that just checks your Initialization method for errors.
[TestInitialize]
public void TestInit()
{
// Nothing goes wrong here as we can see in our smoke test
}
[TestMethod]
[Description("Tests the InitializeMethod")]
[Tag("SmokeTest")]
public void SmokeTest()
{
TestInit();
}
Caveat?
Resources are not automatically recognized by Statlight. You need to add them manually. What resources you need to add manually can be discovered by using the smoke test. To add a resource manually, you need to add the following code:
public static void Get()
{
Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
{
Source =
new Uri(
"/org.vanderbiest.Shell;component/Assets/Styles/BaseStyle.xaml",
UriKind.RelativeOrAbsolute)
});
}
Testing UIElements requires the -b option.
When you run your Silverlight Unit Tests in Visual Studio, the browser will load the XAP file and launch all the tests. The default with StatLight is that it runs without a browser. Luckily for us we can test our XAML bindings using the -b option. Statlight has its own browser process window so that tests will run in a browser context.
Reporting using StatLight
StatLight.exe -x=MyTestXapFile.xap -b -ReportOutputFile=C:\temp\test.xml
Description
Why? StatLight is a commandline utility that will execute your tests in an automated environment.
Reports.
Howto?
- You can install StatLight as a NuGet Package.
- Grab the latest build on CodePlex from their TeamCity Server.
Visual Studio Silverlight Unit Test Result Viewers
Usage? Instead of running in a browser window or launch a command line process, directly view your Unit Test Results in Visual Studio.
AgUnit
Installation
Download: AgUnit on CodePlex
Copy the extracted files from AgUnit-0.4-for-ReSharper-6.0.zip into the “Bin\Plugins\” folder of your ReSharper installation
(default C:\Program Files\JetBrains\ReSharper\v6.0\Bin\Plugins), create this folder if it does not exist. Delete any previous versions of AgUnit you may have in this folder.
Caveat
As you will see with XAML binding tests… Async is currently not working…
Unit Test Result Viewer for StatLight
Download from Visual Studio Gallery
Overall, the plugin did not help me at all. I experienced the following problems:
- Test Project should not be located in a Solution Folder (the assembly will not be recognized by the Result Viewer Tool)
- I could not make it work (after placing StatLight in my Appdata/Local directory), I must did something wrong
Conclusion
There are still some Caveats and there isn’t very much documentation on the net but you can make it work as I described in this blog post.






