Sunday, 22 April 2012

SharePoint 2010 and unit tests (from Visual Studio 2010/MSTest.exe)

It’s been possible to run unit tests/integration tests for SharePoint 2010 within Visual Studio 2010 since VS2010 SP1, but I’m starting to wonder if the steps to enable this are widely known. Whilst writing another article, I did an internet search and didn’t find any useful guides on page 1 of my results. Indeed, many of the top search results contain information which is now out-of-date, such as the “Unit testing with SharePoint 2010 development” article on the usually good www.nothingbutsharepoint.com. However, I won’t be the first to write about this and I suspect the info is out there if you really go looking – but I’m going to do my bit and write the steps down here too.

The key issue here is being able to call into the SharePoint API from a unit test (usually referred to as an integration test). ‘Pure’ unit tests which do not call SharePoint objects have always been fine. The prerequisite for being able to run SharePoint integration tests are:

From there, just follow the process below.

The process - running SP2010 unit/integration tests from Visual Studio 2010

  1. Configure Visual Studio 2010  to allow Test projects (i.e. VS projects which contain tests) to be targeted for .NET 3.5 (the framework version SharePoint 2010 uses):

    The framework version for a Visual Studio project can be configured in the project properties, but I’ve always needed to perform a one-off task (per dev VM) – edit the devenv.exe.config file to allow VS to retarget test projects. These steps are listed on MSDN at Possible Additional Steps to Enable Re-targeting of Test Projects to .NET Framework 3.5, but for completeness I’ll summarise them here:

    - Close Visual Studio if open
    - Open Windows Explorer to C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\
    - Take a backup copy of devenv.exe.config
    - Open the original devenv.exe.config file in Notepad
    - Paste in the entries listed in the ‘Possible Additional Steps..’ link above. Take note that there is an appSettings key as well as the main set of bindingRedirect entries
    - Save the config file
    - Reopen Visual Studio

  2.  Create a Test project and ensure it gets targeted to .NET 3.5:

    There are a couple of routes to doing this, made slightly confusing that the ‘Test Project’ template which targets 3.5 is listed underneath a confusingly-named ‘Test Documents’ heading in the dialog. Either use that one (and check it does target 3.5), or use the main ‘Test Project’ template and go on to retarget it from .NET 4 to .NET 3.5. I’ll show that process here:

    CreateTestProject

    Once the project has been created, go into the project properties and on the Application tab, ensure the Target Framework setting is ‘.NET Framework 3.5’:

    RetargetTestProject

    You’ll see a dialog warning that the project must be closed and reopened – click ‘Yes’ to do this.

  3. Ensure the ‘Platform target’ of the project is set to ‘Any CPU’:

    TestProject_AnyCPU
  4. Ensure the .testsettings file specifies tests should run in a 64-bit process:

    You should now have a couple of .testsettings files in your Visual Studio solution. The deafult one is called Local.testsettings, and we need to edit this one – but note if you use any other file, you’ll need to edit that too. On the Hosts tab, ensure the ‘Run tests in 32 bit of 64 bit process’ option is set to 64-bit:

    TestSettings_64bit

The result

You should now be able to write tests which call into the SharePoint API. For example, here’s a slightly theoretical test showing I can call a utility class which uses SPSite/SPWeb objects:

   1: [TestMethod()]
   2: public void GetRootTeamSiteTitleTest()
   3: {
   4:     string expected = "BVT test"; 
   5:     string actual;
   6:     actual = CobCiHelper.GetRootTeamSiteTitle();
   7:     Assert.AreEqual(expected, actual);
   8: }

..where the code in the CobCiHelper class being called looks like this:

   1: public static string GetRootTeamSiteTitle()
   2: {
   3:     string title = null;
   4:     using (SPSite site = new SPSite(Urls.Homepage))
   5:     {
   6:         using (SPWeb web = site.RootWeb)
   7:         {
   8:             title = web.Title;
   9:         }
  10:     }
  11:     return title;
  12: }

If your test should pass, you’ll see something like this (but either way your text should execute successfully):

TestPassed

Running SharePoint integration tests within TFS automated builds

The process above helps you run tests manually from within Visual Studio, but note that it does not help if you want to run the same tests from within an automated build. Unfortunately, integration tests which call the SharePoint API are not currently supported in Team Foundation Server 2010/Visual Studio 2010. ‘Pure’ unit tests, or those which use a mocking framework such as Typemock can be used though. Let’s hope this challenge goes away in the next wave of technologies.