But it works on my PC!

The random thoughts of Richard Fennell on technology and software development

Mocking out calls in unit tests to a TFS Server using Typemock

If you are developing custom application using the TFS API then there is a good chance you will want to mock out the calls to your TFS server to enable better testing of the business logic in your application. The architecture of the TFS API does not lend itself to mocking using the standard means provided in most auto-mocking frameworks i.e there is not an interface for all the objects you care about. However, with Typemock Isolator you can fake the classes required, as Isolator can fake an instance of virtually any class.

So say we wanted to write a simple build monitor application for TFS Team Build system, we need to connect to a TFS server, get a list of historic builds, then select the last successful one. So our business logic method is as follows

/// <summary>
///  Gets the last successful build
/// </summary>
public static IBuildDetail GetLastNonFailingBuildDetails(string url, string projectName, string buildName)
    using (TeamFoundationServer tfs = new TeamFoundationServer(url))
        IBuildServer buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer));
        return buildServer.QueryBuilds(projectName, buildName).Last(b => b.Status == BuildStatus.Succeeded || b.Status == BuildStatus.PartiallySucceeded);

To test this, you would usually need a TFS server, with a set of historic build data already on it, but with Typemock you can avoid this requirement. OK we have to write bit of supporting code, but most of it would be common to a suite of tests, so the effort will not be too high overall and by doing it you get a test that can be run as part of the build process.

To be able to unit test our business logic (the last line of code in reality in this sample) we need to mock the call to the TeamFoundationServer (which is usually the blocking point for most mocking frameworks) and then mock the call to get the IBuildServer and return a set of data (which is usually possible with mocking frameworks).

Using Typemock we can get around these problems, the comments for each step are inline with the code.

public class TFSTests
    public void The_last_completed_and_non_failed_build_can_be_found()
        // Arrange
        // Create the fake TFS server
        var fakeTfsServer = Isolate.Fake.Instance<TeamFoundationServer>();
        // Swap it in the next time the constructor is run
        // Create a fake build server instance
        var fakeBuildServer = Isolate.Fake.Instance<IBuildServer>();
        // Set the behaviour on the TFS server to return the build server
        Isolate.WhenCalled(() => fakeTfsServer.GetService(typeof(IBuildServer))).WillReturn(fakeBuildServer);
        // Create some test data for the build server to return
        var fakeBuildDetails = CreateResultSet(new List<BuildTestData>() {
              new BuildTestData() {BuildName ="Build1", BuildStatus = BuildStatus.Failed},
              new BuildTestData() {BuildName ="Build2", BuildStatus = BuildStatus.PartiallySucceeded},
              new BuildTestData() {BuildName ="Build3", BuildStatus = BuildStatus.Failed},
              new BuildTestData() {BuildName ="Build4", BuildStatus = BuildStatus.Succeeded},
              new BuildTestData() {BuildName ="Build5", BuildStatus = BuildStatus.PartiallySucceeded},
              new BuildTestData() {BuildName ="Build6", BuildStatus = BuildStatus.Failed}
        // Set the behaviour on the build server to return the test data, the nulls mean we don’t care about parameters passed
        Isolate.WhenCalled(() => fakeBuildServer.QueryBuilds(null, null)).WillReturn(fakeBuildDetails);
        // Act
        // Call the method we want to test, as we are using a fake server the parameters are actually ignored
        var actual = TFSMocking.BuildDetails.GetLastNonFailingBuildDetails("http://FakeURL:8080/tfs", "FakeTeamProject", "FakeBuildName");
        // Assert
        Assert.AreEqual("Build5", actual.BuildNumber);
    /// <summary>
    /// A helper method to hide the Typemock code used to create each build results set
    /// </summary>
    /// <param name="builds">The parameters to populate into the build results</param>
    /// <returns>A set of build results</returns>
    private IBuildDetail[] CreateResultSet(List<BuildTestData> builds)
        var fakeBuilds = new List<IBuildDetail>();
        foreach (var build in builds)
            // Create a fake build result instance
            var fakeBuildDetails = Isolate.Fake.Instance<IBuildDetail>();
            // Set the properties, in this sample we only set a couple of properties, but this can be extended
            fakeBuildDetails.BuildNumber = build.BuildName;
            fakeBuildDetails.Status = build.BuildStatus;
        return fakeBuilds.ToArray();
/// <summary>
/// A holding class for the build data we are interested in faking
/// </summary>
public class BuildTestData
    public string BuildName {get;set;}
    public BuildStatus BuildStatus {get;set;}

This sample is obviously fairly simple, but not that unrealistic. I have certainly written simple logic like this for build status applications. You could of course use some different architecture to make the business logic a bit more testable, but for such as basic requirement it is very tempting to keep it simple.

What I hope this post shows is that there is a way to test this type of logic without the need for a TFS server that has a suitable set of pre-created data and that the basic technique can be extended as much as is required to provide a mocked framework to allow unit testing of more complicated business logic.

Alpha release of TFS 2010 Build Extensions

Back in September I asked the question Does anyone need a VS2010 Custom Build Activity for StyleCop? and a good few people said yes and asked me when the activity would be released.

Well I had forgotten to say that the Codeplex TFS Build Extensions project, which the activity code got included into, has made it’s first public alpha release i.e. a release that means you don’t have to download the source and build it yourself. There is now a downloadable ZIP will just the built assemblies.

But the StyleCop activity is not the only one in releases, the others are:

  • StyleCop
  • Email
  • Twitter
  • Zip
  • File Attributes
  • DateTime
  • Guid
  • Run PowerShell Script
  • Run SQL Command
  • Numerous TFS Build management activities
  • Hyper-V Management
  • Virtual PC Management
  • IIS Website Management

So if you think any of these would be useful in your TFS 2010 Team build please download have a look and feedback any issues you find

TF30040 error when attaching a team project collection

Whilst doing some tidying on a multi-server TFS 2010 system I needed to move a team project collection from one Application Tier (AT) to another. Both ATs (which were not a load balanced pair) shared the same SQL server data tier (DT). It should have been easy using the TFS Administration Console.

I backed up the TPC database using SQL Management tools, the TPC was then detached without any issue from the first AT. I then backed up the SQL DB again in the detached state.

I then I tried to attach the TPC on the second AT. I entered the SQL DT instance name to get a list of TPCs available for attachment and I got the error

TF30040: The database is not correctly configured.
Contact your Team Foundation Server administrator.

So I went back to the original AT and tried a re-attach and got the same error message. Strange I had not changed accounts, the TFSSetup account in use had enough rights to detach the collection but not list one to be attached, strange!

A quick chat with the DBA found the problem, the TFSSetup account in use on both ATs had had its rights trimmed on the SQL server since the system was installed. As soon as it was granted admin rights to the SQL server all was fine with the listing TPCs available for attachment and the actually attaching the TPC on the new server.

Though I did not try it I suspect that as soon as I had the list of available TPCs in the TFS Administration Console I could have removed the extra SQL rights. The TFSService account would be doing the actual attachment, as it had done the detach, the TFSSetup account only need to be used to list the available TPCs.

My experiences getting started with writing custom adaptors for TFS Integration Platform

The TFS Integration Platform is an ALM Rangers project that provides an excellent set of tools to migrate or synchronise source code and/or work items between different TFS servers or TFS server and third party platforms. For many people the supported release on Code Gallery will do all they need. However if you have a need to connect to a system that there is no adaptor for you need the Codeplex version so you can write it yourself. To get the environment up and running, not unsurprisingly, the best place to start is the Getting Started documents.

I did this, I got all the pre-requisites (or so I thought), I download the code and unpack the zip. I ran the  extract_tfs_assemblies.bat to get the local copies of the TFS API assemblies and loaded the MigrationTools.sln in VS2010.

First thing I noted was that I was asked to convert the solution and project files to 2010 format, though they appeared to be the right format to start with. I did this but the report showed no changes, strange!

On loading the solution, other than the ‘TFS offline’ dialog the instructions mention, it also reported it could not load the InstallationCS.csproj file because

C:\Projects\ITIS\IntegrationPlatform\Setup\InstallationCA\InstallationCA.csproj(133,3): The imported project "C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.5\Wix.CA.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

The Wix directory for the current distribution is C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.x, a quick edit of the InstallationCA.csproj in notepad to correct the path fixed this load problem (wonder if that was why VS2010 though it needed to do a solution upgrade?, I could not be bother to roll back to find out.)

I then tried to build the solution, and got around 150 errors, starting with the error

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(292,5): error MSB8009: .NET Framework 2.0/3.0/3.5 target the v90 platform toolset. Please make sure that Visual Studio 2008 is installed on the machine.

I checked and this targets file was there. I had VS2010 and VS2008 installed what could be the problem?

Well it turned out that though I had VS2008 installed I had (for some strange reason lost in the mists of time) not selected the C++ components. Easy to fix you would think. Just go into control panel, into installed products and add the missing features, so I tried to add C++ and got the message

A selected drive is no longer valid. Please review your installation path settings before continuing with setup

I tried inserting DVDs, mounting ISO etc. all to no avail. The found on this forum post, turns out you have to remove VS2008 SP1, add the feature and then re-patch.Once this was done I could build the C++ projects.

As a side note here, I went through this process a couple of time, the first time I also managed to get the TFS adaptor projects references a bit confused. The TFS2008 adaptor projects had ended up referencing the TFS2010 assemblies. This caused a build error due to obsolete calls. This was easily fixed by repointing the references to the copies of the assemblies the extract_tfs_assemblies.bat creates. However if you remember to run extract_tfs_assemblies.bat before opening the solution for the first time this should not be an issue, as all the right assemblies will be on the correct hint paths.

So I now had 36 build errors. The next one I tackled was

Unable to copy file "C:\Projects\ITIS\TestEnv\MigrationTestEnvironment.xml" to "..\..\..\Binaries\Debug\\Test\MigrationTestEnvironment.xml". Could not find a part of the path 'C:\Projects\ITIS\TestEnv\MigrationTestEnvironment.xml'.    MigrationTestLibrary

This  was because the file was actually missing, it is not under the Codeplex source control. This is the XML file defines the adaptors under test. You need to create it based on the test you wish to run, or that is my current understanding. To get around the error (as a start) I just set it ‘copy to output directory’ property to ‘do not copy’ – knowing I would switch this back later

I was now down to 16 errors, all related to the Subversion related projects. These requires, fairly obviously, some Subversion libraries I did not have on my PC. As I did not need to work with Subversion I could have chosen to just remove these projects from the solution, but I thought why not fix it it all. They key again was to follow the readme.txt in the Interop.Subversion project folder. You need to download and unzip the two sets of source for Subversion and Apr.

I was then left with a missing reference to SharpSvn. This I downloaded from http://www.open.collab.net/files/documents/180/2861/SSvn-1.6006.1373.zip and unpacked to the {solution root}/binaries/external/sharpsvn  and made sure the SubversionTCAdapter project reference pointed to this location.

Once all this was done all the projects in the solution built. So nothing too complex really, especially when you follow the instructions in the right order!

So to develop some custom adaptors now then……

Renaming branches in TFS2010

I recently was asked why a client had experienced some unexpected results when merging a development branch back into the main trunk on a TFS 2010 installation.

Turns out the issue was that during some tests that the both the Main and Dev branches had been renamed, and new branches of the same names created. So they had a structure like this:

  Dev Newly created after the rename
  Main Newly created after the rename
  Old_Dev Renamed of Dev
  Old_Main          Renamed of Main


In TFS 2010 behind the scenes a rename is actually a branch and delete process, this meant we ended up with the new branch, but also a deleted branch of the old name. This is not obvious unless you have ‘show deleted items in source control explorer’ enabled in the Visual Studio option


Once you recreate a new branch with the same name as one of the old named branches this deleted branch is replaced by the newly created one, It has taken up the old ‘slot’ (see links at end).This means that when you try to do a merge the merge tools sees this recreated branch as a potential target, and so shows it in the merge dialog. With all the potential confusion that might cause.


So the simple answer is try to avoid renames, and especially try to avoid creating new branches in the same ‘slot’ as deleted/renamed ones.

For a more detailed explanations of that is going on here have a look at this post on renaming branches in TFS and this one on ‘slot mode’ in 2010 version.

Follow up to yesterdays events on ‘enabling agile development with cool tools’

Thanks to everyone who attended yesterdays Black Marble event ‘Enabling agile development with cool tools’, both Gary Short’s and my sessions seemed well received. I was asked if my slides would be available anywhere, well the answer is no. The reason for this is that my session was mostly demo driven, so the slides just set the scene. After a bit of thought, a quick blog post seems a better option;  so this post covers the same basic points as the session. If you are interested in any of the products I would urge you to download them and give them a go. Many are free and all have at least a free fully functional evaluation edition.

So the essence of my session was on the project management/administrative side of agile projects. The key here is communication both inside and outside of the immediate project team. How to we capture and distribute information so it assists the project not hampers it?

Traditionally the physical taskboard, with moving moving some form of postcards around has been the answer. This is a great solution as long as the team is co-located and that there is no need for a detailed on going record of the historic state of the tasks (maybe a requirement for legal reasons, but then maybe a daily digital photo would do?). Anyway many teams find they need to capture this information in some electronic form. In my session I looked at some of the options with TFS2010

What is built into TFS2010?

As TFS has a single work item store you can edit work items with a wide variety of clients. In the box you have tools to edit work items via Visual Studio, SharePoint, Team Web Access as well as the ability to manage work items in Excel and Project.

What if I live in Outlook?

If you want to do all you work item management in Outlook then have a look at Ekobit’s TeamCompanion. This in effect allows you to treat work items in a similar manner to email, and cross between the two. So you can create a work item from an email and vice versa; it also allows the managing work items in batches. This product strikes me was very well suited to an email based support desk or project manager that is meeting or email orientated, maybe dealing with people who do not themselves have access to TFS, just email.

How can I replicate my physical taskboard?

For many teams the capture of the physical taskboard information is the key. I have always found a good way to make sure TFS work items are up to date is to have all the work items associated with the tasks on the taskboard returned via a TFS query and then in Excel, as the daily stand up is done, make sure each task is up to date.

However, some people like to work more visually than that, so in the session I looked at a couple of desktop applications that allow work item management both in a form editing manner and via taskboard like drag and drop operations. These were Telerik’s Work Item Manager and EMC’s TFS Work Bench.

However for many companies adding another desktop application to a controlled IT PC can be a problem so I also had a look at Urban Turtle an add-in to Team Web Access that allows a more visual taskboard approach with in a browser by adding a couple of tabs to those  in the standard Team Web Access product.

But what about outside the team?

All the products I showed in the first half of the session were in essence work item editors, a team could choose to use any or all of them. This does not however really help with getting information out to interested parties beyond the team; for this we need publically accessible Information Radiators. The information on these needs to change over time and be easy to understand.

The output of the team focused tools may be just what you need here, maybe a chart printed out and stuck to a notice board will do, but there are some other options.

The first is that there are a rich set of reports in TFS, available both as Reporting Services reports and Excel charts. Reporting Services is particularity interesting as it can deliver reports to interested parties on a scheduled e.g. the CTO get the project burn down emailed as a PDF every Monday morning. There is also the option to deliver reports to central information sites such as Intranet SharePoint servers for everyone to see.

But what do you do if you want something a bit more striking, something that does not require a person to look on a web site or open their email? Maybe a big screen showing what is going on in the project? I showed two products to do this one was Telerik’s Project Dashboard and the other a version our Black Marble internal BuildWallboard, written using the TFS API.

So in summary, in my opinion the key differentiator for TFS over ALM solutions built for a set of different vendors products is that there is a single store for all work items so a wide range of editing an reporting tools can be bought to bear without having to worry over whether the information you are working with is the going to be passed correctly between the various components of the system.

So again I would urge you that if you use TFS have a look at these product, and the many others that are out there, given them a go and see which ones may assist your process. Remember agile is all about continuous improved isn’t it, so give it a try

Preparing for my session next week on ‘enabling agile development with cool tools’

I have spent today preparing my presentation and demos for the Black Marble event next week Enabling Agile Development with Cool Tools. I will be presenting with Gary Short of DevExpress. He is going to be talking about refactoring under the intriguing title ‘How to Eat an Elephant’.

My session will be on the tools to aid the project management side of the ALM process. Specifically the tools available for TFS 2010 both those ‘out the box’ and from third party vendors. I only have a hour slot, so I have had to be selective as there are may ‘cool tools’ to choose from. So after some thought I have chosen

Urban Turtle 
Telerik Work Item Manager and Project Dashboard
Ekobit TeamCompanion
EMC TFS Work Bench

Should be a good session, there are certainly some great tools in this list.

TF215097 error when using a custom build activity

Whist trying to make use of a custom build activity I got the error

TF215097: An error occurred while initializing a build for build definition \Tfsdemo1\Candy: Cannot create unknown type '{clr-namespace:TfsBuildExtensions.Activities.CodeQuality;assembly=TfsBuildExtensions.Activities.StyleCop}StyleCop'

This occurred when the TFS 2010 build controller tried to parse the build process .XAML at the start of the build process. A check of all the logs gave no other information other than this error message, nothing else appeared to have occurred.

If I removed the custom activity from the build process all was OK and the build worked fine.

So my initial though was that the required assembly was not loaded into source control and the ‘version control path to custom assemblies’ set. However on checking the file was there and the path set.

What I had forgotten was that this custom activity assembly had a reference to a TfsBuildExtensions.Activities assembly that contained a base class. It was not that the named assembly was missing but that it could not be loaded because a required assembly was missing. Unfortunately there was no clue to this in the error message or logs.

So if you see this problem check for references you might have forgotten and make sure ALL the required assemblies are loaded into source control on the control path for custom assemblies used by the build controller

Adding a Visual Basic 6 project to a TFS 2010 Build

Adding a Visual Basic 6 project to your TFS 2010 build process is not are hard as I had expected it to be. I had assumed I would have to write a custom build workflow template, but it turned out I was able to use the default template with just a few parameters changed from their defaults. This is the process I followed.

I created a basic ‘Hello world’ VB6 application. I had previously made sure that my copy of VB6 (SP6) could connect to my TFS 2010 server using the Team Foundation Server MSSCCI Provider so was able to check this project into source control.

Next I created a MSbuild script capable building the VB project, as follows

<Project ToolsVersion="4.0" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <TPath>C:\Program Files\MSBuild\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>
    <TPath Condition="Exists('C:\Program Files (x86)\MSBuild\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks')">C:\Program Files (x86)\MSBuild\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks </TPath>
  <Import Project="$(TPath)"/>
    <VBPath>C:\Program Files\Microsoft Visual Studio\VB98\VB6.exe</VBPath>
    <VBPath Condition="Exists('C:\Program Files (x86)\Microsoft Visual Studio\VB98\VB6.exe')">C:\Program Files (x86)\Microsoft Visual Studio\VB98\VB6.exe</VBPath>
    <ProjectsToBuild Include="Project1.vbp">
      <!-- Note the special use of ChgPropVBP metadata to change project properties at Build Time -->
  <Target Name="Default">
    <!-- Build a collection of VB6 projects -->
    <MSBuild.ExtensionPack.VisualStudio.VB6 TaskAction="Build" Projects="@(ProjectsToBuild)" VB6Path="$(VBPath)"/>
  <Target Name="clean">
    <Message Text="Cleaning - this is where the deletes would go"/>

This used the MSBuildExtensions task to call VB6 from MSBuild, this MSI needed to be installed on the PC being used for development. Points to note about this script are:

  • I wanted this build to work on both 32bit and 64bit machines so I had to check both the “Program Files” and “Program Files (x86)” directories, the Condition flag is useful for this (I could have used an environment variable as an alternative method).
  • The output directory is set to $(OutDir). This is a parameter that will be passed into the MSBuild process (and is in turn set to a Team Build variable by the workflow template so that the build system can find the built files and copy them to the TFS drop directory).

This MSBuild script file can be tested locally on a development PC using the MSBUILD.EXE from the .NET Framework directory. When I was happy with the build script, I stored it under source control in the same location as the VB project files (though any location in source control would have done)

The next step was to create a new Team Build using the default build template with a workspace containing my VB6 project.

The first thing to edit was the ‘Items to Build’. I deleted whatever was in the list (sorry can’t remember what was there by default). I then added the build.xml file I had just created and stored in source control


I then tried to run the build, this if course failed as I needed to install VB6 (SP6) and the MSBuildExtensions on the build server. Once this was done I tried the build again and it work. The only issue was I got a warning that there were no assemblies that Code Analysis could be run against. So I went into the build’s parameters and switched of code analysis and testing as these were not required on this build.

So the process of build ingVB6 on TFS 2010 turned out to much easier than I expect, it just goes to show how flexible the build system in TFS 2010 is. As long as you can express your build as an MSBUILD file it should just work.

You can’t edit a TFS 2010 build workflow template with just Team Explorer installed

I tried to open a TFS 2010 build template within the Visual Studio shell (the bit that gets installed when you put Team Explorer onto a PC) and saw the error “The document contains errors that must be fixed before the designer can be loaded”.


At the bottom of the screen it showed that all the underling assemblies could not be found.

The solution is simple, install a ‘real version’ of Visual Studio, I put on Premium. It seems that the shell does not provide all the assemblies that are needed. Once I did this I could edit the XAML with no problems