Ask a questionAsk a question
 

AnswerTeam Build extensions

  • Friday, August 18, 2006 12:55 PMolgaF Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hello!

    I need a perform some custom operations if build solutions in my Team Build Type completed succesfully and all tests was succseeded. How can i do this? What variables or build properties should I use in the choose conditions?

    Thank you in advance,

    Olga

Answers

  • Friday, August 18, 2006 1:38 PMAaron HallbergMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    This is actually rather complicated to directly detect within MSBuild - the TestToolsTask (which is responsible for actually running your tests) has ContinueOnError true, which converts all errors into warnings such that the build can continue even when tests fail.  This means that you cannot distinguish test success / failure by the Targets which get executed.  There are no properties which get set on test failure within MSBuild either, so there's nothing to include in conditions, etc.

    You can, howevber, distinguish the case you are interested in in code by writing a custom task.  There is a property in the BuildData class returned from the GetBuildDetails web method called GoodBuild that is set to true when compilation and tests succeed and false otherwise.  This value is set in the AfterTest target, so if you override a target that occurs after this one, you should be fine.  I would suggest AfterEndToEndIteration - this will already weed out cases where compilation has failed, since this target only gets executed when compilation is successful.  You would want something like this in TfsBuild.proj:

        <UsingTask TaskName="MyNamespace.HandleCompilationAndTestSuccess" AssemblyFile="MyAssembly.dll"/>

        <Target Name="AfterEndToEndIteration">

            <HandleCompilationAndTestSuccess TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)" />

        </Target>

    Then, in your HandleCompilationAndTestSuccess task's Execute method, you can check the value of GoodBuild with some code like this:

        TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(TeamFoundationServerUrl);

        BuildStore buildStore = (BuildStore)tfs.GetService(typeof(BuildStore));

        if (buildStore.GetBuildDetails(BuildUri).GoodBuild)

        {

            // Do custom logic here to handle compilation and test success.

        }

    Note that this assumes you have defined properties in your task named TeamFoundationServerUrl and BuildUri.  Hope this helps!

    -Aaron

  • Thursday, September 21, 2006 5:27 PMAaron HallbergMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Ouch - sorry about that.  I was mistaken about this - the GoodBuild property was added to the BuildData class subsequent to RTM and is not available in Team Build v1.  There is, in fact, no way to retrieve the GoodBuild flag from Team Build in v1...  We will certainly address this issue in a future release.

    For now, however, there is a workaround for this particular problem (i.e. programmatically determining whether tests have passed for a particular build) - the GetTestResultsForBuild method, which returns an array of TestResultData objects, each of which has a RunPassed property that signifies whether or not the test run passed.  Additional properties can even be used to retrieve the number of individual test failures, successes, etc.

    I've posted an example on my blog that illustrates this workaround:  http://blogs.msdn.com/aaronhallberg/archive/2006/09/21/764951.aspx

    Sorry for all the confusion,

    Aaron

All Replies

  • Friday, August 18, 2006 1:38 PMAaron HallbergMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    This is actually rather complicated to directly detect within MSBuild - the TestToolsTask (which is responsible for actually running your tests) has ContinueOnError true, which converts all errors into warnings such that the build can continue even when tests fail.  This means that you cannot distinguish test success / failure by the Targets which get executed.  There are no properties which get set on test failure within MSBuild either, so there's nothing to include in conditions, etc.

    You can, howevber, distinguish the case you are interested in in code by writing a custom task.  There is a property in the BuildData class returned from the GetBuildDetails web method called GoodBuild that is set to true when compilation and tests succeed and false otherwise.  This value is set in the AfterTest target, so if you override a target that occurs after this one, you should be fine.  I would suggest AfterEndToEndIteration - this will already weed out cases where compilation has failed, since this target only gets executed when compilation is successful.  You would want something like this in TfsBuild.proj:

        <UsingTask TaskName="MyNamespace.HandleCompilationAndTestSuccess" AssemblyFile="MyAssembly.dll"/>

        <Target Name="AfterEndToEndIteration">

            <HandleCompilationAndTestSuccess TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)" />

        </Target>

    Then, in your HandleCompilationAndTestSuccess task's Execute method, you can check the value of GoodBuild with some code like this:

        TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(TeamFoundationServerUrl);

        BuildStore buildStore = (BuildStore)tfs.GetService(typeof(BuildStore));

        if (buildStore.GetBuildDetails(BuildUri).GoodBuild)

        {

            // Do custom logic here to handle compilation and test success.

        }

    Note that this assumes you have defined properties in your task named TeamFoundationServerUrl and BuildUri.  Hope this helps!

    -Aaron

  • Tuesday, August 22, 2006 2:26 PMolgaF Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    This works, thank you!
  • Thursday, September 21, 2006 2:23 PMpoulrh Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    I was looking over this solution and it looked as if it was just what the doctor ordered, unfortunately it seems that the property "GoodBuild" doesn't exist...

    I'm using the 2006.04 VS2005 SDK, with Microsoft.TeamFoundation.Build.Common.dll built 10/03-2006 01:04, I even analysed Microsoft.TeamFoundation.Build.Proxy.BuildData with Lutz Reflector and was unable to find any reference to the property "GoodBuild" which was referenced in the sample...

    Anybody have any ideas what might be wrong?

  • Thursday, September 21, 2006 5:27 PMAaron HallbergMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Ouch - sorry about that.  I was mistaken about this - the GoodBuild property was added to the BuildData class subsequent to RTM and is not available in Team Build v1.  There is, in fact, no way to retrieve the GoodBuild flag from Team Build in v1...  We will certainly address this issue in a future release.

    For now, however, there is a workaround for this particular problem (i.e. programmatically determining whether tests have passed for a particular build) - the GetTestResultsForBuild method, which returns an array of TestResultData objects, each of which has a RunPassed property that signifies whether or not the test run passed.  Additional properties can even be used to retrieve the number of individual test failures, successes, etc.

    I've posted an example on my blog that illustrates this workaround:  http://blogs.msdn.com/aaronhallberg/archive/2006/09/21/764951.aspx

    Sorry for all the confusion,

    Aaron

  • Friday, September 22, 2006 8:58 AMpoulrh Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Well, that explains why I couldn't find it, thanks for the quick response and solution (tested and works) :)
  • Monday, October 09, 2006 6:13 PMalexdresko Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Tested and works..