Silverlight Toolkit unit test project template to try to put some TDD in your project ! ...most probably you were disappointed by it because it’s fairly poor...
All those issues can find an explanation in the fact that the Silverlight framework is a subset of the .NET one making them incompatible with each other.
However, even though these frameworks are different, they’re also very similar. Thanks to this, we will be able to go around the limitation stated above and set up a solution to properly unit test our Silverlight libraries. This solution relies on two parts: structure of the Silverlight projects and then unit testing them within the visual studio framework.
One of the major secrets of a long running application resides in its architecture. This goes the same for the GUI (Graphical User Interface). We’re often tempted to consider the GUI as a whole monolithic bloc:
“GUI is easy, not complex enough to structure it” “anyway, if I decide to change my user interface, I’ll probably change the whole layer, so it’s ok to mix everything here”
Good practices don’t stop at the service layer ! A good structured GUI will allow you to optimize its testability while abstracting models from views. I’m not here to remind you of the MVVM pattern, the idea here is to go one step further by physically abstracting the different parts to leverage flexibility.
I’ll be taking the example of an application exposing web services to a Silverlight light client. (It could as well be a Silverlight only application, its structure would remain the same).
Silverlight projects architecture
The above architecture is composed of 3 RIA projects and 1 Web project:
This library holds (like you could guess) the application views, either controls or pages. This will help us isolate the GUI behaviors (you know, the dirty fixes you do to please the user). All references to converters or ViewModels will be handled through Binding to “StaticResources”.
Here, we’ll isolate the GUI intelligence (or even business rules) using ViewModels, or also converters for example. We’ll also add the service references to this project (proxy generation) because this is what our models will use to manage data. If you could test only one project, this is THE library you’d want to test !
This is our main application, and actually the only “Silverlight Application” project. It references the other libraries and will use them through application resources (App.xaml). To be able to run the application without issues, the trick here is to add the ServiceReferences.ClientConfig of the ViewModels project as a link in order to have the service information at runtime. Without this, your app will start and crash at the first service client instantiation, the service references not being present in the application.
The Web project is exposing our web services (of course tested as well :)). It also exposes one xap file : the main Silverlight project (which will contain the two other libraries).
Now that we structured our application, we can clearly identify the critical library that needs testing: ViewModels. Because this is a sensible library, we want to take advantage of the Microsoft unit test framework of VS 2010, for all the reasons I mentioned earlier. Here follows, imho, one of the most clean way to do so:
and activate the library local copy, this will force the test framework into using them instead of the default .NET ones.
Unit test project local copy of DLLs
Congrats, You’ve just made this unit test library running with the VS 2010 Unit Test framework under a Silverlight runtime!
You are nearly there, almost ready to start developing (yes, because you’re using TDD remember ? :) ! A couple of things left to do to make sure you maximize the use of the framework:
Using TFS up to 2008 <TestContainer Include="$(OutDir)\%2aTests.dll" />
Using VS2010, open local.testsettings, go to Data & Diagnostics, check the Code Coverage option and via Configuration, select your Silverlight ~Views assembly.
We know how much a testing framework impacts the development life-cycle. A bad productivity tool (like the SL Toolkit way of testing) and your whole TDD cycle (red, green, red, green...) is jammed ! This is why, even if this solution has an additional cost (manually referencing libraries), I find it an acceptable one when I compare it to the shift in efficiency I get in my every day job. And this is without mentioning the comfort of having the CI build run the tests and the code coverage metrics …