Friday, March 19, 2010

Steps to run the Windows Phone 7 Unit Test Framework successfully

Thanks to assistance from Jeff Wilcox of Microsoft, I now have the Windows Phone 7 Unit Test Framework running successfully!

Here are the steps to get it running:

1) Download/install Visual Studio 2010 Express for Windows Phone from here.
2) Download the zip file containing the 2 unsigned DLLs from Jeff Wilcox's website.
3) Unzip the 2 DLLs. Then, right-click each DLL individually and select "Properties".
4) In the Properties window for each DLL, click the "Unblock" button. (DLLs off the net are blocked for safety by default.)
5) Launch Visual Studio 2010 Express for Windows Phone and create a new Windows Phone project.
6) Add References to the 2 DLLs that you have just unblocked to this Windows project:
* Microsoft.Silverlight.Testing
* Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight
8) DON'T create any separate class libraries. For now, the unit testing framework requires that all tests/supporting classes be INSIDE the Windows project.
9) DO create a sub-folder in the Windows project to hold code (eg. "CodeLibrary").
10) Create a sub-folder within "CodeLibrary", and name it "Tests".
11) Add a class to the Tests folder, named something like "CustomerViewModelTests.cs"
12) In the class, add the following using statements:

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

13) Add the [TestClass] attribute above the class declaration.
14) Create a test method with the [TestMethod] attribute, something like this:

[TestMethod]
public void Constructor_CustomerInput_IsHappy1()
{
    Assert.IsTrue(true, "It worked!");
}

15) Finally, for the test framework to recognize your tests, you must add code to the code-behind class for the MainPage XAML file.
16) Open the file MainPage.xaml.cs
17) Add the same 2 using statements that you added to the test class:

using Microsoft.Phone.Controls;
using Microsoft.Silverlight.Testing;

18) Add the following lines of code (thanks to Jeff Wilcox for this) at the end of the constructor, just below the SupportedOrientations assignment

const bool runUnitTests = true;

if (runUnitTests)
{
    Content = UnitTestSystem.CreateTestPage();
    IMobileTestPage imtp = Content as IMobileTestPage;

    if (imtp != null)
    {
        BackKeyPress += (x, xe) => xe.Cancel = imtp.NavigateBack();
    }
}

19) Create another folder within the "CodeLibrary" sub-folder named "ThirdParty".
20) Within this folder, create a class called "ButtonService.cs" and paste in the following code. This code comes from Patrick Cauldwell's blog entry here; it adds support for binding ICommand classes to controls via a custom attribute, Command. The Command attribute is a standard feature in WPF and later versions of Silverlight, but not available by default in the Windows Phone 7 implementation of Silverlight:

public static class ButtonService
{
    // Modified from Patrick Cauldwell's original ButtonService class
    // here: http://www.cauldwell.net/patrick/blog/MVVMBindingToCommandsInSilverlight.aspx

    private static readonly DependencyProperty _commandProperty;

    static ButtonService()
    {
         _commandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(ButtonService),
            new PropertyMetadata(OnCommandChanged));
    }

    public static ICommand GetCommand(DependencyObject dependencyObject)
    {
        return (ICommand)dependencyObject.GetValue(_commandProperty);
    }

    public static void SetCommand(DependencyObject dependencyObject, ICommand value)
    {
        dependencyObject.SetValue(_commandProperty, value);
    }

    private static void OnCommandChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dpceArgs)
    {
        if (dependencyObject is Button)
        {
            string parameter = dependencyObject.GetValue(_commandProperty).ToString();
            Button button = (Button)dependencyObject;
            ICommand command = (ICommand)dpceArgs.NewValue;
            button.Click += delegate(object sender, RoutedEventArgs arg) { command.Execute(parameter); };
        }
    }
}

20) Your environment is now configured! Proceed to the tutorial: Building a Windows Phone 7 app with MVVM pattern, using TDD and mock objects.

No comments: