Configuring TDD-style isolated tests for Windows Phone

This article describes the setup instructions for configuring an environment to run isolated unit tests that are intended to run quicky, easily and often to enable test driven development. For integration tests that access isolated storage, web services or phone features, see the WP7-CI project.

This configuration works with all features of the Silverlight Unit Testing framework, including asynchronous tests.

NOTE: These instructions describe the setup for unit MSTest. Why? I personally prefer NUnit, but I use MSTest for my integration tests because of its support for asynchronous Silverlight tests and my preference for a consistant test framework trumps my preference for NUnit.

Before continuing, it is assumed that you have created a Windows Phone application.

Adding a test project

  1. Add a “Silverlight Class Library” project to your solution and select “Silverlight 4″ as the version
  2. Add a reference to your Windows Phone project
  3. Add a reference to System.Xml and System.Windows.Browser
  4. Add a reference to Microsoft.Silverlight.Testing and Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight from the Silverlight Toolkit (not the WP7 version)

Referencing Windows Phone assemblies

Since this is a Silverlight 4 project, accessing Phone assemblies should be avoided. However, some assemblies, like Microsoft.Phone.Reactive, may be necessary.

Since the assemblies won’t be in the “Target Framework Directory” (Silverlight 4 in this project), you have two choices on how you reference them:

  1. Copy the assemblies to your project from %programfiles%\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone 1 and reference them from there
  2. Add the following snippet to your tests project file after the <ProjectExtensions> that contains <SilverlightProjectProperties> and reference the assemblies from their original location.

<PropertyGroup>
  <WindowsPhoneFrameworkDirectory Condition=" '$(WindowsPhoneFrameworkDirectory)' == '' ">
    $(FrameworkPathOverride)\Profile\WindowsPhone
  </WindowsPhoneFrameworkDirectory>
  <ResolveAssemblyReferencesDependsOn>
    $(ResolveAssemblyReferencesDependsOn);AppendWindowsPhoneAssemblyPath
  </ResolveAssemblyReferencesDependsOn>
</PropertyGroup>
<Target Name="AppendWindowsPhoneAssemblyPath">
  <PropertyGroup>
    <AssemblySearchPaths>
      $(AssemblySearchPaths);$(WindowsPhoneFrameworkDirectory)
    </AssemblySearchPaths>
  </PropertyGroup>
</Target>

Either way, you must make sure Copy Local is set to true for any Windows Phone specific assemblies

1 For Mango, use %programfiles%\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone71

Adding a simple test

For the sake of having a test to run, let’s create a simple one now.

Create a class called “SampleTest”:

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class SampleTest
{
    [TestMethod]
    public void AlwaysPasses()
    {
        Assert.IsTrue(true);
    }
}

Running the tests from Visual Studio

  • Visual Studio Test: Silverlight tests are not supported by the built in test runner
  • TestDriven.NET: Run as Silverlight tests
  • ReSharper: Install the AgUnit plugin (you might need to disable the MSTest plugin for AgUnit to work correctly)

Running the tests from the command line (or CI server)

Use the StatLight command line utility:

statlight.exe -d="path\to\assembly.dll" -o=MSTest -v=Feb2011 -r="path\to\log.xml"

By default, StatLight outputs the results in its own format. Alternatively, you can:

Posted in unit-testing, windows-phone | Leave a comment

Writing asynchronous unit tests with Rx and the Silverlight Unit Testing Framework

The Reactive Extensions provide a great way for composing asynchronous actions, particularly on Windows Phone where IO operations are asynchronous-only.

The Silverlight Unit Testing framework (including my CI-supporting port) supports asynchronous unit tests, but if you’ve attempted to use them with Rx you’ve likely run into a few problems.

Avoiding asynchronous tests

In reality, the simplest way to do an asynchronous test is to avoid making it asynchronous. There are two ways of synchronously testing asynchronous APIs that are based on Rx:

If you are writing an isolated unit test and using a “System.Reactive” build of the framework, you can use the Rx Testing Framework to simulate asynchrony without having to write an actual asynchronous test. If you are using the Windows Phone “baked” build (Microsoft.Phone.Reactive), however, the testing framework is not available to you.

The other way is to block until the first value is returned by using First. This will not work with a number of built in asynchronous actions (like HTTP requests) as they internally utilise the UI thread to return the value, so blocking the UI thread results in a hang.

Controlling the stack

On the surface, creating asynchronous tests seems fairly simple and involves three steps:

  1. Have your test class inherit Microsoft.Testing.Silverlight.WorkItemTest
  2. Mark your test method with [Asynchronous]
  3. Call base.TestComplete() when you are done

This works well until your tests fail, either from a failed assertion or from an unhandled Rx call to OnError. When that happens, the error will bubble to the surface and the application will terminate. The problem lies in the call stack, simplified below:


Microsoft.VisualStudio.TestTools.UnitTesting.Assert()
Your.Code.TestClass.TestMethod()
System.Windows.dll!System.Net.Browser.ClientHttpWebRequest.InvokeGetResponseCallback()
mscorlib.dll!System.Threading.ThreadPool.WorkItem.doWork()
mscorlib.dll!System.Threading.Timer.ring()

When the exception is thrown by the assertion, it reaches the top of the stack and the application is terminated. The code that throws the error needs to be called by the testing framework in order for it to register the failure.

In order to re-introduce the testing framework into the stack, the WorkItemTest base class provides the EnqueueCallback method:

void EnqueueCallback(Action testCallbackDelegate)

While we could call this method directly for each call to the observer, the Rx framework already provides a mechanism for controlling execution: schedulers. The IScheduler interface provides the means to schedule work, and the ObserveOn method marshals observer calls to a scheduler.

Here’s an adapter implementation of IScheduler that marshals calls to a WorkItemTest class. It also cancels any pending actions when the test completes to avoid executing any asynchronous test case after the test has completed, since doing so can cause an exception to be thrown if the following test is sycnrhonous

public class WorkItemTestScheduler : IScheduler, IDisposable
{
    private readonly WorkItemTest test;
    private readonly CompositeDisposable scheduledActions = new CompositeDisposable();

    private bool disposed = false;

    public WorkItemTestScheduler(WorkItemTest test)
    {
        this.test = test;

        IDisposable completionSubscription = 
            Observable.FromEvent<TestMethodCompletedEventArgs>(
                h => test.UnitTestHarness.TestMethodCompleted += h,
                h => test.UnitTestHarness.TestMethodCompleted -= h
            )
            .Take(1)
            .Subscribe(_ => Dispose());

        scheduledActions.Add(completionSubscription);
    }

    public DateTimeOffset Now
    {
        get { return DateTimeOffset.Now; }
    }

    public IDisposable Schedule(Action action, TimeSpan dueTime)
    {
        if (disposed)
        {
            return Disposable.Empty;
        }

        if (dueTime != TimeSpan.Zero)
        {
            throw new NotSupportedException("Only immediate schedules are supported");
        }

        var disposable = new BooleanDisposable();

        scheduledActions.Add(disposable);

        test.EnqueueCallback(() =>
        {
            if (!disposable.IsDisposed)
            {
                action();
            }
        });

        return Disposable.Create(() => scheduledActions.Remove(disposable));
    }

    public IDisposable Schedule(Action action)
    {
        return Schedule(action, TimeSpan.Zero);
    }

    public void Dispose()
    {
        scheduledActions.Dispose();

        disposed = true;
    }
}

To make things easier, we’ll introduce an extension method that creates the scheduler for us:

public static class ObservableExtensions
{
    public static IObservable<T> ObserveOnTest<T>(this IObservable<T> source, WorkItemTest test)
    {
        return source
            .ObserveOn(new WorkItemTestScheduler(test));
    }
}

Writing an example test

Here is an example test that attempts to load content from a URL. If the assertion fails or if the server is down, the test framework will log the error and continue execution:

[TestClass]
public class SampleTestClass : WorkItemTest
{
    [Test]
    [Asynchronous]
    public void LoadUrlContent()
    {
        var request = WebRequest.CreateHttp("http://blog.richardszalay.com");

        Observable.FromAsyncPattern<WebResponse>(
            request.BeginGetResponse, request.EndGetResponse
            )()
            .ObserveOnTest(this)
            .Subscribe(response =>
            {
                Assert.IsTrue(response.ContentLength > 1024);

                TestComplete();
            });
    }
}

Posted in Rx, unit-testing, windows-phone | 1 Comment

Practical support for custom light/dark theme resources on Windows Phone 7

Windows Phone 7′s dark/light themes, which allow the user to choose between white-on-black or black-on-white, expose default resource keys for your application to consume. However, since this support doesn’t extend to declaring your own light/dark resources, I thought I’d look into a practical solution.

I had a few requirements for the implementation:

  • It not should require user code to select between specific resources
  • It should support standard resource dictionary files and not require specific naming
  • It should not have a runtime performance penalty
  • It should work in the Visual Studio “cider” designer
  • It should work in Expression Blend

The result is a solution that manages 4 (or 4.5, depending on how you look at it) of those 5, and involves a subclassed ResourceDictionary

namespace ThemeManagement
{
    /// <summary>
    /// Provides automatic selection of resources based on the current theme
    /// </summary>
    public class ThemeResourceDictionary : ResourceDictionary
    {
        private ResourceDictionary lightResources;
        private ResourceDictionary darkResources;

        /// <summary>
        /// Gets or sets the <see cref="ResourceDictioary"/> to use when in the "light" theme
        /// </summary>
        public ResourceDictionary LightResources
        {
            get { return lightResources; }
            set
            {
                lightResources = value;

                if (!IsDarkTheme && value != null)
                {
                    MergedDictionaries.Add(value);
                }
            }
        }

        /// <summary>
        /// Gets or sets the <see cref="ResourceDictioary"/> to use when in the "dark" theme
        /// </summary>
        public ResourceDictionary DarkResources
        {
            get { return darkResources; }
            set
            {
                darkResources = value;

                if (IsDarkTheme && value != null)
                {
                    MergedDictionaries.Add(value);
                }
            }
        }

        /// <summary>
        /// Determines if the application is running in the dark theme
        /// </summary>
        private bool IsDarkTheme
        {
            get
            {
                if (IsDesignMode)
                {
                    return true;
                }
                else
                {
                    return (Visibility)Application.Current.Resources["PhoneDarkThemeVisibility"]
                        == Visibility.Visible;
                }
            }
        }

        /// <summary>
        /// Determines if the application is being run by a design tool
        /// </summary>
        private bool IsDesignMode
        {
            get
            {
                // VisualStudio sometimes returns false for DesignMode, DesignTool is our backup
                return DesignerProperties.GetIsInDesignMode(this) ||
                    DesignerProperties.IsInDesignTool;
            }
        }
    }
}

To test it out, I will create a page that contains an Image wrapped in a Border with the intention of using resources for the ImageSource and BorderBrush, respectively:

<Border BorderThickness="5" BorderBrush="{StaticResource ImageBorderBrush}">
    <Image Source="{StaticResource ThemedImage}" />
</Border>

(Notice that it’s still using StaticResource)

Next, I created two resource dictionaries in /Resources/Light.xaml and /Resources/Dark.xaml, which looked like this:

<!-- Light.xaml -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <SolidColorBrush x:Key="ImageBorderBrush" Color="Red" />
    <BitmapImage x:Key="ThemedImage"
                 UriSource="/ThemeManagement;component/Content/ImageLight.png" />
</ResourceDictionary>

 

<!-- Dark.xaml -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <SolidColorBrush x:Key="ImageBorderBrush" Color="Green" />
    <BitmapImage x:Key="ThemedImage"
                 UriSource="/ThemeManagement;component/Content/ImageDark.png" />
</ResourceDictionary>

NOTE: ThemeManagement is the name of the project

Finally, I added the custom resource dictionary to the App.xaml:

<Application.Resources>
    <custom:ThemeResourceDictionary>
        <custom:ThemeResourceDictionary.LightResources>
            <ResourceDictionary Source="/ThemeManagement;component/Resources/Light.xaml" />
        </custom:ThemeResourceDictionary.LightResources>
        <custom:ThemeResourceDictionary.DarkResources>
            <ResourceDictionary Source="/ThemeManagement;component/Resources/Dark.xaml" />
        </custom:ThemeResourceDictionary.DarkResources>
    </custom:ThemeResourceDictionary>
</Application.Resources>

NOTE: ThemeManagement is the name of the project

Now we can take it for a test toast:

  1. Run the app
  2. Push the start button on the phone/emulator
  3. Go to Settings and change the theme to light
  4. Push Back a few times until you’re in the app again

UPDATE: The above test will not work in Mango due to a unfortunate side effect of multitasking. The correct theme will be applied if the application is relaunched from Start.

Dark Theme Light Theme

We can also confirm that it works in Cider by switching to the design view:

However, since Cider cannot change themes, we can only see the dark theme.

Limitations

Unfortunately, this solution does not work in Expression Blend. For some reason, Blend parses the Resource BAML (compiled XAML) itself and manually supports Source and MergedDictionary attributes. Because of this, the custom ResourceDictionary code never runs and we Blend can’t find the resources and you’ll receive a warning when the project is opened.

The workaround is to select a theme file for design time resources (you can do so from the Blend warning dialog). I recommend choosing Light, since Cider forces us to use Dark. It is unfortunate that both themes can’t be supported, though, as Blend is the one environment that supports swapping between them on the fly.

Posted in windows-phone | 3 Comments

Creating a strongly typed reactive wrapper to INotifyPropertyChanged

Practical Ugliness

INotifyPropertyChanged is a great, built-in, way for property change notification to work in the WPF/Silverlight world. Attempting to use it from staticly typed code, however, gets messy:

SomeViewModel viewModel;

viewModel.PropertyChanged += (s,e) =>
    {
        if (e.PropertyName == "TheProperty")
            GetToWork(viewModel.TheProperty);
    };

Things get even worse when we try to make this reactive:

var propertyChangedEvents = Observable.FromEvent(
    h => new PropertyChangedEventHandler(h),
    h => viewModel.PropertyChanged += h,
    h => viewModel.PropertyChanged -= h);

propertyChangedEvents
    .Where(x => x.PropertyName == "TheProperty")
    .Select(x => viewModel.TheProperty)
    .Subscribe(GetToWork);

An Expressive Solution

The extension method below allows you to specify the property you want to watch using an Expression<Func>, keeping things nice for the compiler:

Edit: Updated once it was tested (and simplified)

public static class NotifyPropertyChangeReactiveExtensions
{
    // Returns the values of property (an Expression) as they change, 
    // starting with the current value
    public static IObservable<TValue> GetPropertyValues<TSource, TValue>(
        this TSource source, Expression<Func<TSource, TValue>> property)
        where TSource : INotifyPropertyChanged
    {
        MemberExpression memberExpression = property.Body as MemberExpression;

        if (memberExpression == null)
        {
            throw new ArgumentException(
                "property must directly access a property of the source");
        }

        string propertyName = memberExpression.Member.Name;

        Func<TSource, TValue> accessor = property.Compile();

        return source.GetPropertyChangedEvents()
            .Where(x => x.EventArgs.PropertyName == propertyName)
            .Select(x => accessor(source))
            .StartWith(accessor(source));
    }

    // This is a wrapper around FromEvent(PropertyChanged)
    public static IObservable<IEvent<PropertyChangedEventArgs>>
        GetPropertyChangedEvents(this INotifyPropertyChanged source)
    {
        return Observable.FromEvent<PropertyChangedEventHandler,
            PropertyChangedEventArgs>(
            h => new PropertyChangedEventHandler(h),
            h => source.PropertyChanged += h,
            h => source.PropertyChanged -= h);
    }
}

GetPropertyValues returns an IObservable of the values of the property as they change, starting with the current value.

You can then use it like so:

viewModel.GetPropertyChangeValues(x => x.TheProperty)
    .Subscribe(GetToWork);

I hope this method can be as useful to you as it has been to me.

Posted in .NET, Rx | 3 Comments

Error installing Windows Phone 7 Series SDK

Now that Windows Phone 7 Series has been opened up a little, I was quick to download the SDK CTP. Unfortunately, I had some problems installing it (possibly caused by the recently uninstalled VS 2010 beta 2 on my machine).

The installation would go fine until it tried to install Silverlight 4, at which time the installation stopped and gave me the error message below. (Also of note, that helpful “View Log” link just took me to the Microsoft homepage)

I had already uninstalled all things Visual Studio and .NET 4, so I snooped a little further and uninstalled all Silverlight tools and runtimes. I even tried installing the Silverlight 4 RC developer runtime manually in an attempt to get past it as a dependency of the installer. This didn’t work either, hitting me with a random error number (1622) and a link to a Microsoft page reiterating the error number and an odd message about writing to a temp folder.

In the end, I came up with a workaround to using the Silverlight installer exe. I’ll document it here for anyone else who comes across the same problem:

  1. Download the Silverlight 4 RC Developer Runtime
  2. Extract the exe to a temp folder using 7zip (or a 7z-supporting application)
  3. Run silverlight.msi
  4. Extract Silverlight.msp from silverlight.7z and run it
  5. Run silverlightdev.msp
  6. Re-run the Windows Phone 7 SDK setup and let it continue the installation
Posted in windows-phone problem workaround | 1 Comment

Massive SUO file causes Visual Studio to hang when doing pretty much anything

I’ve been dealing with horribly slow performance from Visual Studio 2008 (SP1) for a few weeks now. We’re talking seriously slow performance. Like 30-40 seconds of unresponsiveness to save the solution; 20-30 seconds of unresponsiveness after compilation if there were any errors.

Today, after taking a few memory dumps to send to Microsoft, I set out to look for network references (an idea from a workmate). I didn’t find any (nor did I expect to), but I did find a 250MB (!) SUO (Solution User Options) file.

I have no idea how the SUO file got so large, but deleting completly fixed the problem. Visual Studio has returned to it’s usual speediness. I do regret, though, not making a copy of the SUO to send to Microsoft. Next time, perhaps.

Posted in Visual Studio.NET | 5 Comments

Executing Powershell from CruiseControl.NET on 64-bit Windows

If you try to execute a Powershell script from a CruiseControl.NET build on a 64-bit OS, you’ll get the following error:

File ~filename~.ps1 cannot be loaded because the execution of scripts is disabled on this system. Please see “get-help about_signing” for more details.

If you google around, you’ll be told to execute Set-ExecutionPolicy. Unfortunately, on 64-bit, that won’t fix your problem.

The issue is that CruiseControl.NET is 32-bit and the default powershell on 64-bit Windows is 64-bit. When a 32-bit process accesses SOFTWARE registry keys, the request gets redirected to HKLM\Software\Wow6432Node. This results in powershell looking for the wrong key and thus getting the default value.

To work around the problem, execute the following at an elevated command prompt:

%windir%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe “Set-ExecutionPolicy RemoteSigned”

In finding this solution it prompted me to realise that, in 64-bit Windows, c:\windows\system32 is 64-bit and c:\windows\SysWOW64 is 32-bit. And then my head exploded.

Posted in 64-bit, cruisecontrol.net, powershell | 2 Comments