Unit testing phone applications is not common. Partly, because these applications tend to be UI-focused and there is not too much logic to talk about in the first place. Partly, because the lack of tooling support. I am not a big unit tester myself, since I’ve mostly focused on UX recently.
However, our latest Windows Phone project simply cried out for unit testing. It has an extremely complicated inner logic with many complexity layers. We had a reference iOS app that we could turn to for verifying the results of the difficult calculations, but not much more. Most new new features increased the difficulty of these calculations by a whole new dimension. We had tons of calculations we need to be sure stayed valid as the code evolved. So, I began to look at Windows Phone unit testing.
At first, I stumbled upon Jeff Wilcox’s Silverlight Unit Test Frameworks. This is a test harness that runs on a Windows Phone device or the emulator. Here is a screenshot from Jesse Liberty’s intro blog post on the topic.
There are quite a few pros and cons for this framework. The big pro is that it runs on the actual environment, on the same .NET Compact Framework, etc. as the actual application. This didn’t help me much, since the #1 thing I wanted to test was the calculation logic, which is UI agnostic. The big con is that it doesn’t run in a regular unit test runner. Resharper won’t execute it, you can barely hack it into the build process. But the big turn-off for me was that you can’t double click on a failed test and be taken to the right line of code in Visual Studio. You have to do a lot of code navigation and emulator / phone tapping to run a single test in debug mode to figure out what’s wrong.
Let’s create a new Windows Phone Class Library, this will be our code being tested, called TestMe:
Then, another one, which will contain our tests, called TestMe.Test:
Both of them should be Windows Phone 7.1.
Now, if you want to add the nunit.framework dll to the TestMe.Test project, it will fail.
Here is the Message Box text so that search engines can find it:
"nunit.framework, Version=184.108.40.20617, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77" is incompatible with Windows Phone 7.1
In order to add it you should to change the project's target to a compatible framework first.
There are a couple of solutions out there for this one. Most include manually editing the project files and other trickery. However, there is a much simpler solution – use NuGet! Instead of adding the nunit.framework library as a reference, just right click on the project, select Manage NuGet Packages:
Then search for NUnit and install it.
We don’t get any error messages complaining about incompatible runtimes. I don’t know if this is a bug or feature in the NuGet package manager, but I’m happy it works
Reference the TestMe project from the TestMe.Test project, and setup is done.
Let’s write a little bit of test to make sure everything is OK. In the TestMe project, create a Calculator Class:
public class Calculator
public int Add(int x, int y)
And in the TestMe.Test project, let’s write our first test:
public class CalculatorTests
private Calculator _calc;
public void InitTest()
_calc = new Calculator();
public void AddingZerosShouldReturnZero()
int result = _calc.Add(0, 0);
Obviously, this test should fail. But what kind of Test Runners can we use to verify that?
We can use the Nunit test runner, but that hasn’t been installed with the NuGet that we performed above. But we can also use Resharper, which flawlessly recognizes the tests:
And we can also use NCrunch, my new favorite test runner tool, which runs the tests as you type, and provides you almost instantaneous feedback.
And of course, we can just select a test, debug it and stop on any breakpoint:
Note: it is not the goal of this post to teach you how to do unit testing in general. There are much better sources for that
Now that we have the tooling out of the way, we can start writing Windows Phone unit tests just like we do for the desktop framework… Until… well, until we run into a few gotchas with this method. In the next parts of the series, I will look into how you can handle assembly load failures (these are tough), test ViewModels, and tweak Laurent Bugnion’s MVVM Light Toolkit so that it works well with unit testing scenarios.
Aug 08 2012, 10:33 AM