Assert.ThrowsException the async way

The new Windows Phone Test Framework on Visual Studio 2012 Update 2 is a major step in the right direction for testing WP apps.

I particularly like the fact that all tests run on the emulator where they can get the full runtime environment of a real Windows Phone device.

Yet, the test framework still has some pitfalls where we realize it is just not enough!

A few weeks ago I wrote an article about one of these pitfalls, on how to run code in the UI Thread.

Now I’ve stumbled in yet another pitfall, this time on how to run the Assert.ThrowsException with async code!

Microsoft solved this issue on the Windows 8 version of the Test Framework, by adding some Task<Exception> Assert.ThrowsException(Func<Task>) methods, but there is no equivalent in Windows Phone.

This is my personal implementation of these methods for the Windows Phone Test Framework:

public static class AssertExtensions
{
public static Task<T> ThrowsExceptionAsync<T>(Func<Task> action)
where T : Exception
{
return ThrowsExceptionAsync<T>(action, string.Empty, null);
}
public static Task<T> ThrowsExceptionAsync<T>(Func<Task> action, string message)
where T : Exception
{
return ThrowsExceptionAsync<T>(action, message, null);
}
public async static Task<T> ThrowsExceptionAsync<T>(Func<Task> action, string message, object[] parameters)
where T : Exception
{
try
{
await action();
}
catch (Exception ex)
{
if (ex.GetType() == typeof(T))
{
return ex as T;
}
var objArray = new object[] {
"AssertExtensions.ThrowsExceptionAsync",
string.Format(CultureInfo.CurrentCulture, FrameworkMessages.WrongExceptionThrown, message, typeof(T).Name, ex.GetType().Name, ex.Message, ex.StackTrace)
};
throw new AssertFailedException(string.Format(CultureInfo.CurrentCulture, FrameworkMessages.AssertionFailed, objArray));
}
var objArray2 = new object[] {
"AssertExtensions.ThrowsExceptionAsync",
string.Format(CultureInfo.CurrentCulture, FrameworkMessages.NoExceptionThrown, message, typeof(T).Name)
};
throw new AssertFailedException(string.Format(CultureInfo.CurrentCulture, FrameworkMessages.AssertionFailed, objArray2));
}
}

Just copy the above code to your test project and then use it like in this sample:

[TestMethod]
public async Task MyTestMethod()
{
await AssertExtensions.ThrowsExceptionAsync<ArgumentException>(async () =>
{
await Windows.Storage.StorageFolder.GetFolderFromPathAsync("");
});
}

App Package Cleanup

The NuGet team released the 2.5 version yesterday, and along with a bunch of really cool new features, there was one I was particularly interested: the ability to import MSBuild targets and props files!

This means we can now have NuGet packages without any type of assembly, targeting only the project build process.

And if you’ve read this article about the issue with the current build process for Windows 8 and Windows Phone 8 apps, where the Xml Documentation gets bundled in the output packages (APPX and XAP), I have some great news: no more need to change the project file manually, as I just published a NuGet package that does those changes for you!!

All you have to do is run the following command from the Package Manager console window:

InstallPackage AppPackageCleanup

If you have NuGet Package Manager extension installed on Visual Studio, just search for AppPackageCleanup to install the Package.

Note: this package requires NuGet 2.5 as it won’t show up in the search results with previous versions of NuGet!

Windows Phone 8 Unit Testing in the UI thread with VS 2012.2 CTP4

If you’ve been following the news on the upcoming Visual Studio 2012 Update 2 (currently in CTP4), you know that we now have a fully working Unit Tests framework for Windows Phone projects!

Well, this seemed like the perfect opportunity to finally create some unit tests for the Cimbalino Windows Phone Toolkit and test this new test framework, all at once!

Works on my machine

Given that this post will require installing the VS2012.2 CTP 4, a non-final preview version software that has a “go-live” license, I think it’s only proper to apply the WOMM certification to it.

So bottom line, install it at your own risk!

So I started by installing the update, launch Visual Studio 2012, and create a new Windows Phone Unit Test App.

Then, I used NuGet to add a reference to the Cimbalino Windows Phone Toolkit and then added the following test class:

namespace Cimbalino.Phone.Toolkit.Tests.Converters
{
[TestClass]
public class ColorToBrushConverterTests
{
[TestMethod]
public void ConvertWithColorReturnsBrush()
{
var converter = new ColorToBrushConverter();
var expected = Colors.Blue;
var actual = converter.Convert(Colors.Blue, typeof(string), null, CultureInfo.CurrentCulture);
Assert.IsInstanceOfType(actual, typeof(SolidColorBrush));
Assert.AreEqual(((SolidColorBrush)actual).Color, expected);
}
}
}

This simple class will test the ColorToBrushConverter.Convert method as to check for the proper creation of a SolicColorBrush out of a specific Color.

When I ran the test, this is what happened:

Windows Phone Unit Test results
Windows Phone Unit Test results

As you can see here, we got an “Invalid cross-thread access” error message; this is the result of all tests running on a special “test app” inside the Emulator, but the really bad news is that they all run in a background thread.

Apparently, if this was a Windows Store app we could just change the [TestMethod] attribute with the proper [UITestMethod] one as to mark the requirement of running the test in the UI Thread, but unfortunately, the attribute is currently missing from the Windows Phone test framework!

So I decided to fix that and create my very own UITestMethodAttribute, and here it is:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class UITestMethodAttribute : TestMethodAttribute
{
public override TestResult[] Execute(ITestMethod testMethod)
{
TestResult[] result = null;
var ar = new AutoResetEvent(false);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
try
{
result = base.Execute(testMethod);
}
finally
{
ar.Set();
}
});
ar.WaitOne();
return result;
}
}

If you don’t like using the AutoResetEvent, then you can use this alternative version with the new Tasks:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class UITestMethodAttribute : TestMethodAttribute
{
public override TestResult[] Execute(ITestMethod testMethod)
{
var task = ExecuteOnUi(testMethod);
task.Wait();
return task.Result;
}
private Task<TestResult[]> ExecuteOnUi(ITestMethod testMethod)
{
var tsc = new TaskCompletionSource<TestResult[]>();
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
tsc.SetResult(base.Execute(testMethod));
});
return tsc.Task;
}
}

For a usage sample, please refer to the Cimbalino.Phone.Toolkit.Tests project!

Other approaches to solve this issue can be found in this post by Joost van Schaik or this gist from Jake Ginnivan, both relying on just running the necessary code in the UI instead of the full test method as with the above approach.

Cimbalino Windows Phone Toolkit: MultiApplicationBarBehavior

My previous article showed how to use the ApplicationBarBehavior from the Cimbalino Windows Phone Toolkit to build applications with MVVM pattern and still use the Application Bar control without the need for any code-behind.

More than just controlling the app bar from the ViewModel, the ApplicationBarBehavior adds some nice new properties that you can’t find in the native app bar control.

Such is the nature of the IsVisible property found in the buttons and menu items, allowing to change the app bar contents with some ease!

To demonstrate the IsVisible property, I’ll use the sample code from the previous article: this will generate an app bar with 3 buttons, the first two will appear when IsSelectionDisabled = true and the 3rd one will appear when IsSelectionEnabled = true (the opposite state).

This is the recorded animation of what the state changing causes to the application bar buttons visibility:

ApplicationBarBehavior

As you can see, it works perfectly! Well, almost perfectly…

If you look really closely, you’ll notice that the animation doesn’t seem quite that smooth!

By making time go a bit slower, this is what is actually happening:

ApplicationBarBehavior (Slower)

As you can see above, the buttons move before the animation starts!

This behavior is due to the nature of the ApplicationBar.Buttons and ApplicationBar.MenuItems collections: their type is IList, and as such, all we really have is the Add, Remove and Clear methods to manipulate the collection items.

And that is exactly what the ApplicationBarBehavior does behind the scenes: add or remove items when the IsVisible property of each item changes, and that is why we actually see this animation glitch.

Now presenting the MultiApplicationBarBehavior

Fixing this issue will require changing the whole application bar associated with the page, instead of just adding or removing buttons one by one.

And that is exactly what the MultiApplicationBarBehavior does: it allows you to have multiples application bar controls representing different states of the app bar!

Here’s the same app bar from the first article, now using the “multi” version:

<!-- remaining code -->
<Grid x:Name="LayoutRoot" Background="Transparent">
<i:Interaction.Behaviors>
<cimbalino:MultiApplicationBarBehavior SelectedIndex="{Binding ApplicationBarSelectedIndex}">
<cimbalino:ApplicationBar>
<cimbalino:ApplicationBarIconButton Command="{Binding AddItemCommand, Mode=OneTime}" IconUri="/Images/appbar.add.rest.png" Text="add" />
<cimbalino:ApplicationBarIconButton Command="{Binding EnableSelectionCommand, Mode=OneTime}" IconUri="/Images/appbar.manage.rest.png" Text="select" />
</cimbalino:ApplicationBar>
<cimbalino:ApplicationBar>
<cimbalino:ApplicationBarIconButton Command="{Binding DeleteItemsCommand, Mode=OneTime}" CommandParameter="{Binding SelectedItems, ElementName=ItemsMultiselectList}" IconUri="/Images/appbar.delete.rest.png" Text="delete" />
</cimbalino:ApplicationBar>
</cimbalino:MultiApplicationBarBehavior>
</i:Interaction.Behaviors>
<!-- remaining code -->
</Grid>
<!-- remaining code -->

Major difference here is the presence of multiple ApplicationBar entries, but also the MultiApplicationBarBehavior.SelectedIndex property which will allow you to select what app bar you want to show.

Here’s the recording of the app bar transition now:

MultiApplicationBarBehavior

Much nicer, but just to make sure, here is the same animation but about 5 times slower:

MultiApplicationBarBehavior (Slower)

Cimbalino Windows Phone Toolkit: ApplicationBarBehavior

Cimbalino Windows Phone Toolkit The Windows Phone Application Bar has been a true headache for developers since day one, given that this object is not a FrameworkElement.

What this means is that we are unable to apply Styles or Templates to an ApplicationBar object, but most important, we are unable to bind to its properties, something that is a big issue when you what to use MVVM pattern in you apps.

Surely MVVM is not a closed pattern, and as such there are alternatives to overcome this issue (like this one or this one)!

In my case, in order to access the ApplicationBar in my apps in a more ”MVVM‘ed” way, I created the ApplicationBarBehavior that you can find in the Cimbalino Windows Phone Toolkit!

This Behavior, when applied to a PhoneApplicationPage or it’s LayoutRoot element, allows to create and maintain a fully bindable Application Bar, and as such applying a more consistent MVVM pattern.

Here’s a small sample code for it:

<!-- remaining code -->
<Grid x:Name="LayoutRoot" Background="Transparent">
<i:Interaction.Behaviors>
<cimbalino:ApplicationBarBehavior>
<cimbalino:ApplicationBarIconButton Command="{Binding AddItemCommand, Mode=OneTime}" IconUri="/Images/appbar.add.rest.png" Text="add" IsVisible="{Binding IsSelectionDisabled}" />
<cimbalino:ApplicationBarIconButton Command="{Binding EnableSelectionCommand, Mode=OneTime}" IconUri="/Images/appbar.manage.rest.png" Text="select" IsVisible="{Binding IsSelectionDisabled}" />
<cimbalino:ApplicationBarIconButton Command="{Binding DeleteItemsCommand, Mode=OneTime}" CommandParameter="{Binding SelectedItems, ElementName=ItemsMultiselectList}" IconUri="/Images/appbar.delete.rest.png" Text="delete" IsVisible="{Binding IsSelectionEnabled}" />
</cimbalino:ApplicationBarBehavior>
</i:Interaction.Behaviors>
<!-- remaining code -->
</Grid>
<!-- remaining code -->

In this small code sample we can see the ApplicationBarBehavior and in it, some ApplicationBarIconButton (like you would do in the current one), and quickly we notice some new properties like Command, CommandParamenter, and IsVisible (something we can’t even find in the base Windows Phone ApplicationBar); obviously, even the properties Text and IconUri are bindable, allowing for easy localization! ;)

Updated: Reduce the size of your XAP/APPX package!

In my previous post I wrote about an issue with the current build process for Windows 8 and Windows Phone 8 apps, where the Xml Documentation would get bundled in the output packages (APPX and XAP).

A few days later, I started to get some comments over the internet regarding the need to add my fix to all projects in a solution in order to make it fully work, something that turned out to be a bit tedious…

I have now updated the original post with a new solution that will only require you to change the projects that actually have a package output! :)

Please check the original post and update your projects to match the new change!

Reduce the size of your XAP/APPX package: time to take out the trash!

Updated on 20/02/2013

Before you even continue reading this article, I must just address a small warning: the following information has passed the WOMM certification, and as such, this works on my machine…

Works on my machine

Recently, while browsing StackOverflow as I normally do, I found a question that really caught my attention:

Visual Studio packs into WP8 XAP unnecessary XML doc files

If you create Windows Phone 8 App in Visual Studio and reference any libs with XML documentation files supplied from nuget or manually, Visual Studio will automatically pack those XML files into output XAP as well.

In our case this weird behavior of Visual Studio increases XAP size almost twice. (We have 8Mb of xml docs in total.)

There is no such problem for WP7 app projects.

After reading this, I had to confirm this behavior myself! Here’s what I did:

  • Created a blank solution
  • Added two Windows Phone projects, one with the 7.1 SDK and the other with the 8.0.
  • Used NuGet to add Json.net package to both projects
  • Build the solution

These are the XAP files resulting from building each project:

Windows Phone XAP files from both projects

As you can see here, the WP8 version is about 60Kb larger than the WP7 version. That’s 42% larger!!!

Here is the content of the WP7 XAP file:

Windows Phone 7 XAP contents

And this is the content of the WP8 XAP file:

Windows Phone 8 XAP contents

If you look closely on the WP8 version above, you’ll see a Newtonsoft.Json.xml file - that’s the Json.net Xml Documentation!

What is it doing there? Nothing. Can we safely remove it? Most definitely, yes!

My research on why this only happens in Windows Phone 8 lead to the MSBuild process, specifically the ResolveAssemblyReferences task on Microsoft.Common.targets file: this particular task returns a variable called ReferenceCopyLocalPaths, referring to “Paths to files that should be copied to the local directory.” which upon inspection, proved to have our “garbage files”!

To fix this, edit the *.csproj files for your projects that have package outputs (XAP or APPX), and add this to the end of the file, just before the </Project> closing tag:

<PropertyGroup>
<FilesToXapDependsOn>$(FilesToXapDependsOn);BeforeFilesToXap</FilesToXapDependsOn>
</PropertyGroup>
<Target Name="BeforeFilesToXap">
<ItemGroup>
<FilteredPackagingOutputs Remove="@(FilteredPackagingOutputs)" Condition="'%(FilteredPackagingOutputs.OutputGroup)' == 'CopyLocalFilesOutputGroup' AND '%(FilteredPackagingOutputs.Extension)' == '.xml'"/>
</ItemGroup>
</Target>

This custom target will run just before the FilesToXap target, telling MSBuild to remove all XML Documentation files from the list of files to copy.

So far this has proven to work perfectly for my applications, and when I applied it to my WP8 test project, I managed to get a much more reasonable 174KB XAP file!

One final note: although this article focus on Windows Phone, I actually found out that Windows Store Apps are also affected by this issue, and that the same solution can be used to fix the problem!

Error: Nuget.exe exited with code -1073741819

Lately I’ve been getting more and more this type of error from Nuget Package Restore when building my apps:

NuGet -1073741819 error

This seems to be a completely random issue with Nuget, as I see it happening with different projects, and sometimes not even happening at all!

Problem is that I work with some big/complex solutions that have a lot of projects, each one with it’s own packages.config file that can show this issue, so that sums up to a lot of failed builds!

There are actually a few open tickets about this in Codeplex, but given that this issue has been reported a while ago and so far it has not been solved, I thought on tackle this myself!

“If at first you don’t succeed, try and try again”

Following that motto, I thought on changing the Nuget Package Restore process so that it will retry a few times before aborting the build!

The easiest way I found to achieve this goal is just to change the .nuget\NuGet.targets file on the root of the solution. Inside this file, I found the following:

<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
<Exec Command="$(RestoreCommand)"
Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
<Exec Command="$(RestoreCommand)"
LogStandardErrorAsError="true"
Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
</Target>

Above you can see the MSBuild target that actually runs Nuget.exe, and so this is the one I will change to “fix” the issue.

This is my improved RestorePackages target:

<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites" Condition="Exists('$(PackagesConfig)')">
<PropertyGroup>
<NugetLogStandardErrorAsError Condition="'$(OS)' == 'Windows_NT'">true</NugetLogStandardErrorAsError>
<NugetLogStandardErrorAsError Condition="'$(OS)' != 'Windows_NT'">false</NugetLogStandardErrorAsError>
</PropertyGroup>
<Exec Command="$(RestoreCommand)" LogStandardErrorAsError="$(NugetLogStandardErrorAsError)" IgnoreExitCode="True">
<Output TaskParameter="ExitCode" PropertyName="ExitCode" />
</Exec>
<Message Text="Error occurred, #1 retry..." Importance="High" Condition=" $(ExitCode) != 0 " />
<Exec Command="$(RestoreCommand)" LogStandardErrorAsError="$(NugetLogStandardErrorAsError)" IgnoreExitCode="True" Condition=" $(ExitCode) != 0 ">
<Output TaskParameter="ExitCode" PropertyName="ExitCode" />
</Exec>
<Message Text="Error occurred, #2 and last retry..." Importance="High" Condition=" $(ExitCode) != 0 " />
<Exec Command="$(RestoreCommand)" LogStandardErrorAsError="$(NugetLogStandardErrorAsError)" Condition=" $(ExitCode) != 0 " />
</Target>

You can see three consecutive Exec tasks here, each one will run depending on the previous one exit code, and only the last one will actually abort the build.

What this means is that if Nuget fails, we will retry it two more times before aborting the build!

As you can see, this is not a proper fix for the issue, it just bypasses it… so I’m still waiting for a fix on this - and I’m now looking at you, Nuget dev team! ;)