Content

8/03/2011

Unit Testing for Windows Phone


In this article I am going to talk about unit testing for Windows Phone 7.
First, there is no option for a windows phone test project within the IDE.

In our XING-App we use Silverlight Unit Test Framework and NUnit as the provider for test metadata.
We have an additional test project to run unit tests called TestRunner. 
Reference these Microsoft.Silverlight.Testing.dll and Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight.dll assemblies from the Silverlight Unit Test Framework to these project.

Note: You will get a warning about adding silverlight 3 assembly, it is fine and you can click yes to continue.

Set up the testpage
Hide the system tray to have more space if you like.

Register NUnit as the provider for test metadata (attributes etc).  That tells the silverlight testing framework to use the NUnit test attributes instead of the default MSTest attributes.

tell the silverlight testing framework to use the NUnit test attributes
  1.             UnitTestSystem.RegisterUnitTestProvider(
  2.                 new NUnitProvider());

We use an additional project for the unit tests. 
So we need to add assemblies, that contains the tests. 

Add unit tests
  1. settings.TestAssemblies.Add(typeof(Hook).Assembly);

Now any NUnit test fixture you add to the project should work.
Note that you can only have NUnit tests or MSTest tests in a project, not a mixed combination.

Create the testpage and let the unit testing framework take over.

Set the testpage
  1.  var testPage = UnitTestSystem.CreateTestPage(settings)
  2.      as MobileTestPage;
  3.  BackKeyPress += (x, xe) => xe.Cancel =
  4.      testPage.NavigateBack();
  5.  (Application.Current.RootVisual
  6.      as PhoneApplicationFrame).Content = testPage;

Using NUnit
Download the binaries from the nunit-silverlight project and add NUnit.Silverlight.Compatibility.dll and  NUnit.Silverlight.Metadata.dll as reference to the test project.
Tag your unit tests to run specific subsets of tests. When you start your TestRunner-App you can choose to only run tests with a certain tag, a certain set of tags, or not run tests with specific tags

Tagging a testmethod
  1. [Test]
  2. [Tag("UnitTestTag")]
  3. public void AlwaysPass()
  4. {
  5.     Assert.IsTrue(true, "method intended to always pass");
  6. }

Integration Tests
Now combine unit tests (modules) and test it!
For the integration tests we follow our created test plan to chose aggregates.


Id
XXXX


Test Type
Explorative / Serversimulation


Title
Logon is necessary after logout.
Test Goal
Ensure that the user has to log on again after he performs a log off.
Precondition
Same as XXXX
Steps
Automated Test: IntegrationTests.
Expected Result
The network news page is shown.
Note



Our WP7-App has a lot of asynchronous method calls like web service calls.
To test asynchronous methods you will first have to make sure your TestClass inherits from SilverlightTest.
Next, you will need to mark the test method as asynchronous. Finally, you will have to call EnqueueTestCompleted() to tell the test when it has completed.
If you do not call this then the test will never complete.

The XING-App make use of a TestBase class. This class inherits from SilverlightTest and overrides EnqueueConditional.
To make sure all tests end, EnqueueConditional becomes a timeout mechanism. The test will fails and EnqueueTestCompleted is called and the test is really completed.

Asynchronous testmethod timeout
  1.             var timer = new DispatcherTimer();
  2.             timer.Interval = new TimeSpan(0, 0,
  3.                 ConditionalTimeout);
  4.             timer.Tick += delegate
  5.             {
  6.                 // remember
  7.                 // to stop timer or it'll tick again
  8.                 timer.Stop();
  9.                 throw new TimeoutException();
  10.             };
  11.             EnqueueCallback(timer.Start);
  12.             base.EnqueueConditional(conditionalDelegate);
  13.             EnqueueCallback(timer.Stop);

Fake test server
We are in the test process and we do not want to run the tests against the live XING-Server, so we need such as a fake XING server. This fake server also helped us in the development process.
During the development we got no test XING-Accounts. The only way to test was with our live accounts. 

Our fake server is a normal web service and is similar to the XING API. We also have functions like:
  • make many users
  • make visit
  • make many messages
  • make number of contacts
These helper functions are very useful to use this test server and to write easily these integration tests.
It was also very useful to test functionality against this test server. For example, if you need some contact requests.