Home > BUILD, TFS 2010 > TFS 2010 – Customize Build Output changes and MS Tests

TFS 2010 – Customize Build Output changes and MS Tests

November 24, 2010

Recently I have been trying to structure the TFS output to ease deployment of artefacts. The solution contains Web Apps, Windows Services and DB Scripts. As some of you might already be aware of , TFS Server Build output does not reflect your solution and project structure.

First Jim Lab’s solution

So there are a few HACKS to edit your project files and your BUILD process templates. Once you have implemented those HACKs you should be able to output the binaries as intended. Jim Lamb’s CusomizableOutDir post covers how to edit your project files to output as intended.

BEWARE if you are using the DefaultTemplate and Workflow. Ensure you are editing the right sequence and

Edit the Workflow by navigating to Sequence > Run on Agent > Try Compile & Test…. > Run MS BUILD for Project. Edit the properties as shown in the screen below.

Note that the OutDir needs to be cleared


Further changes to the Project files need to be done to ensure the output paths are as desired. Open the .csproj in your solution using a text editor. Scroll to the PropertyGroup corresponding to the Config & platform to change the OutputPath as desired.

<PropertyGroup Condition= ‘$(Configuration)|$(Platform)’ == ‘Release|x86’ >
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath Condition= ‘$(TeamBuildOUtDir)’!=”>$(TeamBuildOutDir)\Win\Console\$(MSBuildProjectName)</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>

FIX for Web projects and _PublishedWebSite

The next problem you probably will run into is the Web projects output. The Web Projects for MSBUILD needs to be edited slightly different from the rest of the project to output into _PublishedWebSite folder. Edit your .csproj as to make the changes as follows –

<PropertyGroup Condition= ‘$(Configuration)|$(Platform)’ == ‘Release|x86’ >
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutDir Condition= ‘$(TeamBuildOUtDir)’!=”>$(TeamBuildOutDir)\Win\UI\$(MSBuildProjectName)</OutDir>

<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>

MSTest and No Test Results

Now you will notice that MS Tests are not running anymore on TFS BUILDs. Another HACK to edit all MSTest project outputs using a macro suggested by Thanks to Christian Lavallee on StackOverflow.

Create a new macro in VS 2010 with shortcut Alt + F8. Add Reference to Microsoft.Build and Import in your macro. I customised the Macro to only work on Test projects as all other deployable projects needed to be hand edited for distinct OutputPath.

I edited the macro to Output all Test projs into a Tests folder as follows

Dim outputTeamBuild = propertyGroup.AddProperty(“OutputPath”, “$(TeamBuildOutDir)\Tests\$(MSBuildProjectName)”)

outputTeamBuild.Condition = “‘$(TeamBuildOutDir)’!=” ”

After completing your changes to macro save it. Now Open your solution with all the projects. Switch to Macro and Run it. Running the Macro checks out your .csproj project files and changes the OutputPath for each qualifying projects.

Now CHECKIN your solution and trigger a BUILD on the server to verify the Output

EDIT: I am now considering rolling out custom Project Templates (Web, MS Test, Win services) for our org with $(TeamBuildOutDir) changes so no macros will need to be run on the solution. I will cover it in a new post as to how I get along.

PROBLEM API restriction: The assembly <<SomeUnitTest.dll>> has already been loaded from a different location

One more Gotcha… and I am done. Interestingly after all this hard work I was pulling my hair off as I ran into API restriction: The assembly <<SomeUnitTest.dll>> has already been loaded from a different location. Fortunately I quickly realised one of our Unit Test assembly (A helper within) was referenced by another Unit test thus outputting it into that bin directory.

TIP: Do ensure your non TEST  projects do not contains the reserve word TEST.

One of my project referenced by MS Test Project was named *TestHelper*. TFS Builds will attempt to run MS Tests named *Test*.dll and try to load it from all referenced projects.

I refactored the code to move all helpers out and renamed TestHelper, and then removed the reference of SomeUnitTest.dll from the consuming project. Built it again… Voila Output as intended and cleanly structured for deployment, MS Tests run fine.

Well nothing is simple right? Who would have thought I need Architecture Validation for Unit Tests as well…

Ok DevOps its all yours now…

Categories: BUILD, TFS 2010
  1. Roy
    November 25, 2010 at 3:49 am

    Gr8 post. It helped me with my TFS builds. Thx Roy

  1. No trackbacks yet.
Comments are closed.