But it works on my PC!

The random thoughts of Richard Fennell on technology and software development

Problem faking multiple SPLists with Typemock Isolator in a single test

I have found a problem with repeated calls to indexed SharePoint Lists with Typemock Isolator 6.0.3. This what I am trying to do…

The Problem

I am using Typemock Isolator to allow me to develop a SharePoint Webpart outside of the SharePoint environment  (there is a video about this on the Typemock site). My SharePoint Webpart uses data drawn from a pair of SharePoint lists to draw a map using Google maps API; so in my test harness web site page I have the following code in the constructor that fakes out the two SPLists and populates them with test content.


   1: public partial class TestPage : System.Web.UI.Page
   2:  {
   3:     public TestPage()
   4:     {
   6:        var fakeWeb = Isolate.Fake.Instance<SPWeb>();
   7:        Isolate.WhenCalled(() => SPControl.GetContextWeb(null)).WillReturn(fakeWeb);
   9:        // return value for 1st call
  10:        Isolate.WhenCalled(() => fakeWeb.Lists["Centre Locations"].Items).WillReturnCollectionValuesOf(CreateCentreList());
  11:        // return value for all other calls
  12:        Isolate.WhenCalled(() => fakeWeb.Lists["Map Zoom Areas"].Items).WillReturnCollectionValuesOf(CreateZoomAreaList());
  13:     }
  15:     private static List<SPListItem> CreateZoomAreaList()
  16:     {
  17:        var fakeZoomAreas = new List<SPListItem>();
  18:        fakeZoomAreas.Add(CreateZoomAreaSPListItem("London", 51.49275, -0.137722222, 2, 14));
  19:        return fakeZoomAreas;
  20:     }
  22:     private static List<SPListItem> CreateCentreList()
  23:     {
  24:        var fakeSites = new List<SPListItem>();
  25:        fakeSites.Add(CreateCentreSPListItem("Aberdeen ", "1 The Road,  Aberdeen ", "Aberdeen@test.com", "www.Aberdeen.test.com", "1111", "2222", 57.13994444, -2.113333333));
  26:        fakeSites.Add(CreateCentreSPListItem("Altrincham ", "1 The Road,  Altrincham ", "Altrincham@test.com", "www.Altrincham.test.com", "3333", "4444", 53.38977778, -2.349916667));
  27:        return fakeSites;
  28:     }
  30:     private static SPListItem CreateCentreSPListItem(string title, string address, string email, string url, string telephone, string fax, double lat, double lng)
  31:     {
  32:         var fakeItem = Isolate.Fake.Instance<SPListItem>();
  33:         Isolate.WhenCalled(() => fakeItem["Title"]).WillReturn(title);
  34:         Isolate.WhenCalled(() => fakeItem["Address"]).WillReturn(address);
  35:         Isolate.WhenCalled(() => fakeItem["Email Address"]).WillReturn(email);
  36:         Isolate.WhenCalled(() => fakeItem["Site URL"]).WillReturn(url);
  37:         Isolate.WhenCalled(() => fakeItem["Telephone"]).WillReturn(telephone);
  38:         Isolate.WhenCalled(() => fakeItem["Fax"]).WillReturn(fax);
  39:         Isolate.WhenCalled(() => fakeItem["Latitude"]).WillReturn(lat.ToString());
  40:         Isolate.WhenCalled(() => fakeItem["Longitude"]).WillReturn(lng.ToString());
  41:         return fakeItem;
  42:     }
  44:     private static SPListItem CreateZoomAreaSPListItem(string areaName, double lat, double lng, double radius, int zoom)
  45:     {
  46:         var fakeItem = Isolate.Fake.Instance<SPListItem>();
  47:         Isolate.WhenCalled(() => fakeItem["Title"]).WillReturn(areaName);
  48:         Isolate.WhenCalled(() => fakeItem["Latitude"]).WillReturn(lat.ToString());
  49:         Isolate.WhenCalled(() => fakeItem["Longitude"]).WillReturn(lng.ToString());
  50:         Isolate.WhenCalled(() => fakeItem["Radius"]).WillReturn(radius.ToString());
  51:         Isolate.WhenCalled(() => fakeItem["Zoom"]).WillReturn(zoom.ToString());
  52:         return fakeItem;
  53:     }
  55: }

The problem is that if I place the following logic in my Webpart

   1: SPWeb web = SPControl.GetContextWeb(Context);
   2: Debug.WriteLine (web.Lists["Centre Locations"].Items.Count);
   3: Debug.WriteLine (web.Lists["Map Zoom Areas"].Items.Count);

I would expect this code to return


But I get


If I reverse two Isolate.WhenCalled lines in the constructor I get


So basically only the last Isolate.WhenCalled is being used, this is not what I expect from the Typemock documentation. .This states that, worst case, the first Isolate.WhenCalled should be used for the first call and the second for all subsequent calls, and actually the index string should be used to differentiate anyway. This is obviously not working. I actually also tried using null in place of the both the index strings and got the same result.

A Workaround

I have managed to workaround this problem with a refactor of my code. In my web part I used to moved all the SPList logic into a pair of methods

   1: private List<GISPoint> LoadFixedMarkersFromSharepoint(SPWeb web, string listName)
   2: {
   3:     var points = new List<GISPoint>();
   5:     foreach (SPListItem listItem in web.Lists[listName].Items)
   6:     {
   7:             points.Add(new GISPoint(
   8:                 listItem["title"], 
   9:                 listItem["address"], 
  10:                 listItem["email addess"], 
  11:                 listItem["site Url"], 
  12:                 listItem["telephone"], 
  13:                 listItem["fax"], 
  14:                 listItem["latitude"], 
  15:                 listItem["longitude"]));
  16:     }
  17:     return points;
  18: }
  20: private List<ZoomArea> LoadZoomAreasFromSharepoint(SPWeb web, string listName)
  21: {
  22:          var points = new List<ZoomArea>();
  24:          foreach (SPListItem listItem in web.Lists[listName].Items)
  25:          {
  26:            points.Add(new ZoomArea(
  27:                 listItem["title"],
  28:                 listItem["latitude"], 
  29:                 listItem["longitude"], 
  30:                 listItem["radius"], 
  31:                 listItem["zoom"]));
  32:          }
  33:          return points;
  34: }

I then used Isolator to intercept the calls to these methods, this can be done by using the Members.CallOriginal flag to wrapper the actual class and intercept the calls to the private methods. Note that I am using different helper methods to create the list of my own data objects as opposed to List<SPListItems>

   1: var controlWrapper = Isolate.Fake.Instance<LocationMap>(Members.CallOriginal);
   2: Isolate.Swap.NextInstance<LocationMap>().With(controlWrapper);
   4: Isolate.NonPublic.WhenCalled(controlWrapper, "LoadFixedMarkersFromSharepoint").WillReturn(CreateCentreListAsGISPoint());
   5: Isolate.NonPublic.WhenCalled(controlWrapper, "LoadZoomAreasFromSharepoint").WillReturn(CreateZoomAreaListAsZoomItems());

My workaround, in my opinion, is a weaker test as I am not testing my conversion of SPListItems to my internal data types, but at least it works

I have had to go down this route due to a bug in Typemock Isolator (which has been logged and recreated by Typemock, so I am sure we can expect a fix soon). However it does show how powerful Isolator can be when you have restrictions in the changes you can make to a code base.Wrapping a class with Isolator can upon up a whole range of options.

Does anyone need a VS2010 Custom Build Activity for StyleCop?

There is a noticeable omission form the tooling for StyleCop that you cannot integrate it into a TFS 2010 Build directly. There is a custom task to do it as part of MSBuild Extension pack, but this is designed for TFS 2008.

So when I had to wire in StyleCop to our 2010 build process I hit a problem, I could

  1. Edit the .csproj files for each project to wire in StyleCop
  2. Use an MSBuild activity in my 2010 build
  3. Write my own custom activity.

I decided to follow the final option, it did not look too bad as the source needed is provided in the StyleCop SDK. Well after a good deal of fiddling I have it basically working. Again I found the process of developing a custom activity a little irritating.

I cannot state enough times the way to do this type of development is

  1. Create the activity, unit testing if possible
  2. Create a WF console application to host it
  3. For each activity property wire it to an argument on the workflow WF console application
  4. Create a test project to run unit tests against this workflow
  5. Only when this all works go down the painful route of getting it linked into a real build

The main problem I had was that StyleCop was running fine, but finding no violation when I knew some were in my test data. This all turned out to be down to where the Microsoft.StyleCop.dll assembly was being loaded from, and whether there were any rules assemblies in the same directory. I have to admit I only got to the bottom of this after getting all the source for StyleCop so I could debug into it!

So I now have the first pass at StyleCop custom activity for TFS 2010, needs some more testing, but I think I am just about there. I intend to get it up on http://tfsbuildextensions.codeplex.com/, just need to make sure it meets all the guidelines.

So is there any interest in this activity?

Running MSDeploy to a remote box from inside a TFS 2010 Build (Part 2)

Another follow up post, this time to the one on MSDeploy. As I said in that post a better way to trigger the MSDeploy PowerShell script would be as part of the build workflow, as opposed to a post build action in the MSBuild phase. Doing it this way means if the build failed testing, after MSBuild complete, you can still choose not to run MSDeploy.

I have implemented this using an InvokeProcess call in my build workflow, which I have placed just before Gated checking logic at the end of the process template.


The if statement is there so I only deploy if a deploy location is set and all the tests passed

BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded And
String.IsNullOrEmpty(DeployLocation) = False

The InvokeProcess filename property is

BuildDetail.DropLocation & "\_PublishedWebsites\" & WebSiteAssemblyName & "_Package\" & WebSiteAssemblyName & ".deploy.cmd"

Where “WebSiteAssemblyName” is a build argument the name of the Project that has been publish (I have not found a way to automatically detect it) e.g. BlackMarble.MyWebSite. This obviously as be set as an argument for the build if the deploy is to work

The arguments property is set to

"/M:http://" & DeployLocation & "/MSDEPLOYAGENTSERVICE /Y”

Again the “DeployLocation” is a build arguement that is the name of the server to deploy to e.g. MyServer

The Result property is set to an Integer build variable, so any error code can be returned in the WriteBuildError

This seems to work for me and I think it is neater than previous solution

How to edit a TFS 2010 build template when it contains custom activities.

I posted a while ago on using my Typemock TMockRunner Custom Activity for Team Build 2010. I left that post with the problem that if you wished to customise a template after you a had added the custom activity you had to use the somewhat complex branching model edit the XAML.

If you just followed the process in my post to put the build template in a new team project and tried to edit the XAML you got the following errors, an import namespace error and the associated inability to render part of the workflow


The best answer I have been able to find has been to put the custom activity into the GAC on the PC what you wish to edit the template on, just there nowhere else the method in the previous post is fine for build agents. So I strongly signed the custom activity assembly, used GACUTIL to put it in my GAC and was then able to load the template without any other alterations. I as also able to add it to my Visual Studio toolbox so that I could drop new instances of the external test runner onto the workflow.

Getting code coverage working on Team Build 2010

If you have VS2010 Premium or Ultimate [Professional corrected error in orginal post]  you have code coverage built into the test system. When you look at your test results there is a button to see the code coverage


You would think that there is easy way to use the code coverage in your automated build process using Team Build 2010, well it can done but you have to do a bit of work.

What’s on the build box?

Firstly if your build PC has only an operating system and the Team Build Agent (with or without the Build Controller service) then stop here. This is enough to build many things but not to get code coverage. The only way to get code coverage to work is to have VS2010 Premium or Ultimate also installed on the build box.

Now there is some confusion in blog posts over if you install the Visual Studio 2010 Test Agents do you get code coverage, the answer for our purposes is no. The agents will allow remote code coverage in a Lab Environment via a Test Controller, but they do not provide the bits needs to allow code coverage to be run locally during a build/unit test cycle.

Do I have a .TestSettings file?

Code Coverage is managed using your solution’s .TestSetting file. My project did not have one of these, so I had to ‘add new item’ it via add on a right click in the solution items.

The reason I had no .TestSettings file was because I started with an empty solution and added projects to it, if you start with a project, such as a web application, and let the solution be created for you automatically then there should be a .TestSettings file created.

In the test settings you need to look at the Data & Diagnostics tab and enable code coverage and then press the configure button, this is important.


On the configuration dialog will see a list of your projects and assemblies. In my case initially I only saw the first and the last rows in the graphic below. I selected the first row, the project containing my production code and tried a build.

THIS DID NOT WORK – I had to added the actual production assembly as opposed to the web site project (the middle row shown below). I think this was the key step to getting it going.

The error I got before I did this was Empty results generated: none of the instrumented binary was used. Look at test run details for any instrumentation problems.  So if you see this message in the build report check what assemblies are flagged for code coverage.


Does my build definition know about the .TestSettings file?

You now need to make sure that build knows the .TestSettings file exists. Again this should be done automatically when you create a build (if the file exists), but on my build I had to add it manually as I created the file after the build.





So when all this is done you get to see a build with test results and code coverage.


Easy wasn’t it!

Next weeks Agile Yorkshire meeting: Some things about testing that everyone should know, ...... but were afraid to ask, in case somebody told them.

It is Agile Yorkshire time again, it is a real shame that due to the move of the meeting from the 2nd Wednesday to the 2nd Tuesday I really struggle to make the events. Particularly irritating this month as this one look really interesting and the speaker, Ralph Williams, from past evidence always is entertaining. To quote the Agile Yorkshire site the session will..

“The presentation will focus on the techniques that testers use to identify their tests, whether working from a requirements specification or on agile teams.

Agile testing books mostly focus on the agile aspects or the technology so this area often gets glossed over. The main sections would be:

    • Equivalence Classes and Boundary Conditions
    • Decision Tables
    • Classification Trees
    • User Focused Testing

There will be a group exercise looking a how these techniques can be applied to the testing of a well known website.

As a group we will go through the process of identifying the testing that is required and in the process explain various test techniques that might be useful to people back in their day jobs.”

For full details see http://www.agileyorkshire.org/event-announcements/10Aug2010

Running SPDisposeCheck as part of a 2010 CI Build

SPDisposeCheck is a great tool for SharePoint developers to make sure that they are disposing of resources correctly. The problem is it is a bit slow to run, a problem as this will mean developers will tend not to run it as often as they should. A good solution to the problem is to run it as part of the continuous integration process. There is are posts on how to do this via unit tests and as a MSBuild task, but I wanted to use a TFS 2010 style build. Turns out this is reasonably straight forward without the need to write a custom activity.

  • I created a build template based on the Default one.
  • After the compile and before the test step I added a InvokeProcess activity


  • I set the InvokeProcess properties as shown below, the edited settings are
    • Arguments: String.Format(“””{0}””””, outputDirectory) (remember you need the enclosing “ if your path could have spaces in it)
    • Filename: To the location of the SPDisposeCheck.exe file
    • Result: A previously created build variable of type Int32



  • This is done with a simple if check. If there are any errors found I write a build error message and set the TestStatus to failed. You might choose to set the build status to fail or any other flag you wish. The potential problem with my solution is that the TestStatus value could be reset by the tests that follow in the build process, but for a basic example of using the tool this is fine.

So it is easy to added a command line tool to the build. The key reason it is so easy is that SPDisposeCheck returns a number that we can use to see if the test passed or failed. hence we did not need to parse any text or XML results file. I wish more tools did this.

IDD Building a breakfast comment to a become process – now there is a leap

Gil at Typemock has been posting about some ideas we discussed over breakfast at the Typemock Partner conference a while ago, I have been a bit slow at commenting, so I though I better add to the conversation. Though Typemock is an excellent mocking framework, for me basic mocking is not its biggest win. All the ‘classic auto mocking’ of interfaces to speed TDD style working is great, but I can do that with any of the .NET mocking frameworks. All they do is mean I don’t have to write my own test stubs and mocks, so saving me time, which is good but not the keep win I was looking for.

For me there is another way to save much more time and that is to reduce my ‘build, deploy, use’ cycle. In the land of SharePoint this is a significant time saving, or at least has been for us. It has meant that I can replace the build, create WSP, deploy WSP, let SharePoint/IIS restart and then view a web part, with a build and view in ASP.NET page that uses Typemock to fake out all to SharePoint calls. This is what Gil has termed Isolation Driven Development (IDD) Now isn’t a three letter _DD name going a bit far, I am even not sure there enough in it for me to write a book!

That said this is a solid technique which can be applied to any complex environment where developers or testers need a means to mock out significant, costly, or just slow components to ease there daily work process, often enabling some manual testing process, thus making them more productive. If you read the TPS books it mentions a lot how workers should optimise their work space to reduce wasted time the spend moving between machines or roles, this is just such a move.

So if you want to use the technique for Sharepoint have a look at my post, I hope it will save you time whether on SP2007 or 2010, or maybe apply same technique to other technologies.

Today’s DDD South West

Thanks to everyone who turned up for my session at DDD South West, and to the organisers for putting the event on so well.

As my session was basically a 1 hour demo of the testing tools in VS2010 there are no slides for me to upload, but if you have any questions ping me an email. I would say that for a good overview of the subject have a look at the book ‘Professional Application Lifecycle Management with Visual Studio 2010: with Team Foundation Server 2010