Unit testing in Silverlight

My team is working on a Silverlight project for the last three months. One of the first issues we encountered was unit testing for the Silverlight libraries.

Unfortunately, this issue is not trivial. Current dev tools, including the VSTS do not support running tests in the traditional way. In order for a Silverlight test to run, it needed to be hosted inside a web page. This is quite problematic when trying to practice TDD and even running the tests on your CI server.

Let's start at the beginning.

The Silverlight Sdk (aka Silverlight tools) contains a project type for Silverlight tests. Simply click New –> Project –> Silverlight and select Silverlight Unit testing Application:

image

As I mentioned before, Silverlight unit tests can only be run under a host web site, so after creating the project, Visual Studio will ask you to create a web site to host the tests.

In the unit testing project, a class will be created with the familiar VSTS test class:

public class Tests  
{
    [TestMethod]
    public void TestMethod1()
    {
        var c = new Class1();

        var result = c.Test();

        Assert.IsTrue(result);
    }
}

To run the tests, simply run the default page in the web site that was created. A browser will be opened with a Silverlight page which runs the tests in the test project:

image

If you look closely at the Silverlight test project, you will see that this is a simple Silverlight app project. The output of the project is a xap file which contains all the test classes. The project contains a App.xaml file. In the startup event you can see the following code:

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

This is actually the creation of the page which runs the tests and displays the results.

Although this is very nice implementation, it doesn't helps us when we are trying to develop in TDD. In order to do that we would like a tool which runs the the inside VS.

AgUnit is a very cool tools which enables us to run tests with Resharper test runner. In order to install it, simply extract the files from the download into C:\Program Files (x86)\JetBrains\ReSharper\v5.0\Bin\Plugins, and you can run the tests with Resharper:

image

This plugin simply simulates a web page and hosts inside the runner process of Resharper the xap file from the test project and runs it’s tests. So, at this stage, you can delete the web site you created…

Tip: notice the prerequisites of the tool. In short, you need to add reference to System.Xml.Linq.

The next step, is to run the tests in the build server. For this we will need to find a tool which can host a Silverlight app. One tool that can do this is StatLight (why didn't they call it StarLight?). This is a command line tool which can be used to run a Silverlight testing project on the dev machine and in a TeamCity build server or using MSBuild:

image

This tool also allows you to TDD, using the –c option. This option will run the tests in the command line and listen to the build of the xap file of the test project. If the xap file will be rebuilt, then it will run the tests again. This is pretty useful and efficient when doing Tdd.

After we dealt with CI, lets make our programming experience more familiar. What if we want to use NUnit? mocking?

Well, Rhino.Mocks has a version compiled for Silverlight (from 3.5 version). Just reference the dll and mock away.

NUnit also has a version for Silverlight. But in order to use it, you'll need to change the App.xaml to use NUnit for the runner. Remember the Application_Start event? This is the initialization of the runner. Microsoft is using a provider model to this framework which enables third party unit testing frameworks to inject there own runner. Add references to all three dlls from the NUnit site, and then simply add this code in the event:

private void Application_Startup(object sender, StartupEventArgs e)  
{
    UnitTestSystem.RegisterUnitTestProvider(new Microsoft.Silverlight.Testing.UnitTesting.Metadata.NUnit.NUnitProvider() );

    RootVisual = UnitTestSystem.CreateTestPage();
}

Change the test code to the standard NUnit syntax:

[TestFixture]
public class Tests  
{
    [Test]
    public void TestMethod1()
    {
        var c = new Class1();

        var result = c.Test();

        Assert.IsTrue(result);
    }
}

And run the tests

That's about all I could find… Do you have more tips on doing testing in Silverlight?

comments powered by Disqus