04
May
10

Windows Phone 7, MVVM and TDD (Part 2 – The first test)

by Peter Daukintis

First, I will create a new project in Visual Studio using the MVVM Light project templates (MVVM Light is not a requirement really it just makes the implementation of MVVM less repetitive – any compatible MVVM framework would do, or you could just roll your own).

NewMVVMLightProject

I got a compatibility warning dialog when I executed this step as the version of the MVVM Light has not been updated to support the Windows Phone application manifest. This is easily fixed by adding the following to the WMAppManifest.xml file in the project.

    <Capabilities>
      <Capability Name="ID_CAP_NETWORKING" />
      <Capability Name="ID_CAP_LOCATION" />
      <Capability Name="ID_CAP_SENSORS" />
      <Capability Name="ID_CAP_MICROPHONE" />
      <Capability Name="ID_CAP_MEDIALIB" />
      <Capability Name="ID_CAP_GAMERSERVICES" />
      <Capability Name="ID_CAP_PHONEDIALER" />
      <Capability Name="ID_CAP_PUSH_NOTIFICATION" />
      <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />      
    </Capabilities>

 

Build and run the application which will start up the emulator and you should see something similar to the following:

MVVMLightAppBaseline

Now add the unit test project as follows:

  • Add a new ‘Windows Phone Application’ project to your solution
  • WP7LoginAddTestProject
  • Rename to WP7Login.Tests
  • Delete the MainPage.xaml file
  • Set the RootVisual to a page created by the unit test framework:
    • Reference the assemblies for the Silverlight Unit Testing Framework to the project (Microsoft.Silverlight.Testing & Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight)
    • AddUnitTestAssembliesForWP7

Edit the app.xaml.cs App constructor so it looks like this (i.e. add the code to set the RootVisual)

        public App()
        {
            UnhandledException += new EventHandler<ApplicationUnhandledExceptionEventArgs>(Application_UnhandledException);

            InitializeComponent();

            RootVisual = UnitTestSystem.CreateTestPage();
        }

Now, set the test project as the solution startup project and run the test project. You should see something like the following:

WP7LoginEmptyUTProjectRunning

Since we haven’t written any tests yet there is nothing to run. So let’s start by creating a very simple test. First add a new class to the Test project called MainViewModelTests (the MVVM Light template provides us with a pre-created MainViewModel class which I will use exclusively for this demonstration). Also, the tests I will write are for demonstrative purposes – in a real life project I would strive for maximum coverage. Adorn the class with the TestClass attribute and derive it from the SilverlightTest class (from the unit test tools).

using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace WP7Login.Tests
{
    [TestClass]
    public class MainViewModelTests : SilverlightTest
    {
        
    }
}

 

Add a test method to the class like so…

        [TestMethod]
        public void UsernameText_SetValue_RaisesPropertyChanged()
        {
            
        }

(I use Resharper code templates here for fast generation of the test  method signature following my preferred naming convention which is Method_Scenario_ExpectedResult).

In order for my proposed ‘UsernameText’ property to take part in data-binding (which is crucial to support MVVM) it must support the INotifyPropertyChanged interface. My first test is to check that this works correctly.

        [TestMethod]
        public void UsernameText_SetValue_RaisesPropertyChanged()
        {
            var mainViewModel = new MainViewModel();

            bool propChanged = false;
            mainViewModel.PropertyChanged +=
                (s, e) =>
                {
                    if (e.PropertyName == "UsernameText")
                    {
                        propChanged = true;
                    }
                };

            mainViewModel.UsernameText = "fred";
            Assert.IsTrue(propChanged);
        }

This is my first go at the test. Please note that the MainViewModel class already supports the INotifyPropertyChanged interface – this is provided by the MVVM Light toolkit (by deriving from ViewModelBase). I have written this code before actually adding the property to the view model so I will also need to add the property.

 

        private string _usernameText;

        public string UsernameText
        {
            get { return _usernameText; }
            set
            {
                if (_usernameText != value)
                {
                    _usernameText = value;
                    RaisePropertyChanged(() => UsernameText);
                }
            }
        }

This is a standard implementation aside from the type-safe RaisePropertyChanged method. This achieves the same end result as the standard version (which takes a string of the property name as a parameter). The problem with this is that if you spell the property name wrong this can lead to some debugging pain. This is implemented as follows:

        private void RaisePropertyChanged<T>(Expression<Func<T>> action)
        {
            RaisePropertyChanged(GetPropertyName(action));
        }

        private static string GetPropertyName<T>(Expression<Func<T>> action) 
        {
            var expression = (MemberExpression)action.Body;
            return expression.Member.Name;
        }

I added these to my view model as helpers to look up the property name automatically from the lambda expression.

Anyway, back to the UsernameText property; once this is added I can go ahead and run the first test…Here are the results…

WP7LoginFirstSuccessfulTest

And, clicking on the one and only test gives some further details:

WP7LoginFirstTestSuccessDetails

So, that’s it – the environment is configured for basic MVVM and so we can run tests against the ViewModel.

Technorati Tags: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Windows Live Tags: MVVM,Part,Visual,Studio,requirement,implementation,framework,version,WMAppManifest,Name,ID_CAP_LOCATION,ID_CAP_SENSORS,ID_CAP_MEDIALIB,ID_CAP_GAMERSERVICES,ID_CAP_PHONEDIALER,ID_CAP_PUSH_NOTIFICATION,ID_CAP_WEBBROWSERCOMPONENT,Build,unit,Application,solution,Rename,Delete,MainPage,RootVisual,Reference,Microsoft,VisualStudio,QualityTools,Edit,code,UnhandledException,EventHandler,ApplicationUnhandledExceptionEventArgs,Application_UnhandledException,InitializeComponent,UnitTestSystem,CreateTestPage,haven,Test,MainViewModelTests,template,MainViewModel,demonstration,Also,life,coverage,Adorn,TestClass,SilverlightTest,tools,TestTools,method,TestMethod,Resharper,generation,signature,convention,Method_Scenario_ExpectedResult,UsernameText,data,interface,PropertyName,Assert,IsTrue,supports,ViewModelBase,_usernameText,result,parameter,pain,Expression,Func,action,GetPropertyName,MemberExpression,Body,Member,Anyway,Here,environment,ViewModel,templates,purposes,helpers,xaml


2 Responses to “Windows Phone 7, MVVM and TDD (Part 2 – The first test)”


  1. 1 Ken
    December 30, 2010 at 4:55 pm

    cool idea to run the SL unit test framework as a WP7 app

  2. 2 Geek
    June 6, 2011 at 9:39 am

    Can you please share the code for this logon screen. This will help me for my ongoing project.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: