Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Phone development and Unit Testing

I'm looking to start a project targeting Windows Phone, but I'm slightly put off by the lack of unit testing support[1].

I'm used to using NUnit/ XUnit for most of my testing needs, with something like NSubstitute for mocking. Near as I can tell, you can't use these frameworks for Windows Phone projects...

Given some investigation, I was wondering if the following scenario would work:

  • Use Visual Studio 2012
  • Create a Portable Class Library project(s) for the View Models and other logic
  • Create other Portable Class Library project(s) for the unit tests
  • Wait for Windows Phone 8 SDK[2], then create the views using that.

By using a Portable Class Library, I'm hoping that the unit tests will be as close as possible to running on the device, without having to crack open the emulator.

Another plus point is that I can see that this solution working within a TFS build environment - so running the tests are part of a CI build...

I was hoping to gauge peoples opinion on if this is a sensible move, or a fools errand...

Thanks,
Kieron

[1] I know there are solutions out there, but none that seem as integrated as full framework testing - I'm talking specifically about support in VS2012/ Resharper for running unit tests without the need for an emulator.

[2] Does anyone know if you can target Windows Phone 7.x using the WP8 SDK?

like image 276
Kieron Avatar asked Oct 19 '12 08:10

Kieron


2 Answers

Update: Unit testing for Windows Phone 8 is supported now.

http://blogs.msdn.com/b/visualstudioalm/archive/2013/01/31/windows-phone-unit-tests-in-visual-studio-2012-update-2.aspx

like image 20
Anirudh Avatar answered Sep 28 '22 08:09

Anirudh


Here's what we do:

  • Abstract phone-specific logic into facades
  • Inject dependencies wherever possible
  • Avoid using any code that requires to run on the UI thread upon construction, this meaning any UI control, ImageSource, basically any System.Windows type that isn't a enumeration (such as Visibility)
  • Heavily rely on ValueConverters to convert business logic into UI logic.

If you do this, then you can use the the build-in Visual Studio unit testing framework, to test Windows Phone projects (not just Portable Class Libraries) with a bit of hackery.

1) First step is to disable strong name validation , this can be done with following Powershell script:

reg DELETE "HKLM\Software\Microsoft\StrongName\Verification" /f
reg ADD "HKLM\Software\Microsoft\StrongName\Verification\*,*" /f
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64")
{
   reg DELETE "HKLM\Software\Wow6432Node\Microsoft\StrongName\Verification" /f
   reg ADD "HKLM\Software\Wow6432Node\Microsoft\StrongName\Verification\*,*" /f
}
Restart-Service msiserver

Notice that it creates a security vulnerability on the machine this is applied to!

2) Second step is to create a Visual Studio Unit Test Project, a regular one, not a Windows Store Unit Test Project.

3) Third step is to include the Windows Phone 8 project as a reference. This works, and you can now use Microsoft Fakes to make mscorlib and System.dll , allowing you to fake types like DateTime in your unit tests, a very handy feature.

4) Fourth step is to get a local copy of the following Windows Phone assemblies (and any additional you need):

  • System.Windows
  • Microsoft.Phone

They can be found in the C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools\MDILXAPCompile\Framework folder.

Copy them locally to a /lib/ folder, and then unload and edit the MSBUILD xml of your Unit Test Project.

Change:

<Reference Include="System.Windows" />
<Reference Include="Microsoft.Phone" />

To

<Reference Include="System.Windows, Version=2.0.6.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, processorArchitecture=MSIL">
  <HintPath>lib\System.Windows.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Phone, Version=8.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e, processorArchitecture=MSIL">
  <HintPath>lib\Microsoft.Phone.dll</HintPath>
</Reference>

Additionally to avoid a warning when compiling, add following element to the first <PropertyGroup>

<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>

Reload, compile, run the tests. Voilà, and you're done. You can even integrate this with the Microsoft Code Coverage functionality.

NB: Unit Testing is not officially supported by the Windows Phone Division, this is a workaround found by my team and I at the Skype Division.

Bonus answer:

Does anyone know if you can target Windows Phone 7.x using the WP8 SDK?

enter image description here

like image 68
Claus Jørgensen Avatar answered Sep 28 '22 08:09

Claus Jørgensen