tags:

views:

98

answers:

2

How can I run a certain cleanup task after my "Test" target runs, regardless of whether the Test target succeeded or failed (like the try...finally construct in C#/Java).

+2  A: 

The Target element has an OnError attribute you could set to a target to execute on error, but as it only executes if the target is in error, it only solves half your scenario.

Have you considered chaining together targets to represent the test 'steps' you'd like to execute?

<PropertyGroup>
    <TestSteps>TestInitialization;Test;TestCleanup</TestSteps>
</PropertyGroup>

The 'TestInitialization' target is where you can perform any test initialization, the 'Test' target executes the test, the 'TestCleanup' target does any sort of post test clean up.

Then, execute these targets using the CallTarget task, using the RunEachTargetSeparately attribute set to True. This will execute all the targets, regardless of success or failure.

The complete sample is below:

<Project DefaultTargets = "TestRun"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >

    <!-- Insert additional tests between TestInitialization and TestCleanup as necessary -->
    <PropertyGroup>
        <TestSteps>TestInitialization;Test;TestCleanup</TestSteps>
    </PropertyGroup>

   <Target Name = "TestRun">

      <CallTarget Targets="$(TestSteps)" RunEachTargetSeparately="True" />

   </Target>

    <Target Name = "TestInitialization">
        <Message Text="Executing Setup..."/>
    </Target>

    <Target Name = "Test">
        <Message Text="Executing Test..."/>

        <!-- this will fail (or should unless you meet the conditions below on your machine) -->
        <Copy 
          SourceFiles="test.xml"
          DestinationFolder="c:\output"/>
    </Target>

    <Target Name = "TestCleanup">
        <Message Text="Executing Cleanup..."/>
    </Target>

</Project>
Zach Bonham
Just came to testing this now, and it works perfectly. Thanks for the rather complete example.
ripper234
np! Glad it worked!
Zach Bonham
A: 

Or use to call your target in the error case, and DependsOnTargets or CallTarget to call your same target in the normal case.

dan moseley