1

I am modifying a Nant build script to run some unit tests. I have different targets for locally run tests and tests to be run on team city.

<target name="run-unit-tests">  
   <property name="test.executable" value="tools\nunit\nunit-console.exe"/>
   <call target="do-unit-tests"/>
</target>

<target name="run-unit-tests-teamcity"> 
   <property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>      
   <call target="do-unit-tests"/>
</target>

in the target do-unit-tests I set up which test assemblies are run by setting a property and calling for NCover to do a code coverage run as follows:

<target name="do-unit-test">
   <property name="test.assemblies" value="MyProject.dll">
   <call target="do-unit-test-coverage" />
</target>

<target name="do-unit-test-coverage">
   <ncover <!--snip -->
           commandLineArgs="${test.args}"
   <!--snip-->
   </ncover>
</target>

As you can see in the ncover part I need a property called "test.args". This property depends on "test.assemblies"

ie: <property name="test.args" value="${test.assemblies} <!--snip -->" />

test.args needs to be set up differently between the locally run unit test and the one on team city...so I'm trying to figure out how to set this up.

if i put the property for test.args in "do-unit-test" after the property "test.assemblies" I can't specify one test.args if do-unit-test is called by run-unit-tests and another for run-unit-tests-teamcity.

I've been trying to do something like the following in "do-unit-test":

<if test="${target::exists('run-unit-tests-teamcity')}">
 <property name="test.args" value="..." />
</if>

but obviously that doesn't work because the target will always exist.

What I'd like then is to test if my current target do-unit-test has been called by run-unit-tests-teamcity

Is this possible? I can't see it in the Nant documentation? Since its not there it either means that it will be a feature in the future or that I'm not understanding how things are specified in a Nant build script.

Dharman
  • 30,962
  • 25
  • 85
  • 135
mezoid
  • 28,090
  • 37
  • 107
  • 148

2 Answers2

2

You can define properties in one target, and use their values in the other... For example, you can define

<target name="run-unit-tests">
   <property name="test.executable" value="tools\nunit\nunit-console.exe"/>
   <property name="test.extratestargs" value="foo,bar,baz"/>
   <call target="do-unit-tests"/>
</target>

<target name="run-unit-tests-teamcity">
   <property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>         
   <property name="test.extrtestargs" value="foo,baz,quux,xyzzy"/>
   <call target="do-unit-tests"/>
</target>

<target name="do-unit-test-coverage">
   <property name="test.args" value="${test.assemblies} ${test.extratestargs} <!--snip -->" />
   <ncover <!--snip -->
           commandLineArgs="${test.args}" >
   <!--snip-->
   </ncover>
</target>


Or if you need them to be structured completely differently, not just have some different values, take advantage of the fact that the property substitution is delayed:


<?xml version="1.0"?>

<project name="nanttest">

        <target name="run-unit-tests">
           <property name="test.executable" value="tools\nunit\nunit-console.exe"/>
           <property name="test.args" value="foo bar -assembly ${test.assemblies} baz" dynamic="true"/>
           <call target="do-unit-test"/>
        </target>

        <target name="run-unit-tests-teamcity">
           <property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
           <property name="test.args" value="foo,baz,quux /a:${test.assemblies} xyzzy" dynamic="true"/>
           <call target="do-unit-test"/>
        </target>

        <target name="do-unit-test-coverage">
           <echo message="test.executable = ${test.executable}, test.args = ${test.args}" />
        </target>

        <target name="do-unit-test">
           <property name="test.assemblies" value="MyProject.dll"/>
           <call target="do-unit-test-coverage" />
        </target>


</project>

user@host:/tmp/anttest$ nant run-unit-tests
[...snip...]
run-unit-tests:
do-unit-test:
do-unit-test-coverage:
     [echo] test.executable = tools\nunit\nunit-console.exe, test.args = foo bar -assembly MyProject.dll baz
BUILD SUCCEEDED
Total time: 0 seconds.

user@host:/tmp/anttest$ nant -D:teamcity.dotnet.nunitlauncher=nunitlauncher run-unit-tests-teamcity
[...snip...]
run-unit-tests-teamcity:
do-unit-test:
do-unit-test-coverage:
     [echo] test.executable = nunitlauncher, test.args = foo,baz,quux /a:MyProject.dll xyzzy
BUILD SUCCEEDED
Total time: 0 seconds.

If you really, really just need to know if you're running in TeamCity, then this should help:

<target name="run-unit-tests-teamcity">
   <property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>         
   <property name="running.in.teamcity" value="true"/>
   <call target="do-unit-tests"/>
</target>

Stobor
  • 44,246
  • 6
  • 66
  • 69
  • your second example won't work because it requires {test.assemblies} which is created in the target do-unit-tests....but yes, I do need the properties to be structured completely differently for each one – mezoid Dec 23 '08 at 22:58
  • Ah - I missed that NAnt works differently from Java Ant - you need to explicitly set dynamic="true" in those property definitions for it to work as I described. – Stobor Jan 05 '09 at 00:17
  • That worked awesome! Thanks for that. I had no idea about setting dynamic to true.... – mezoid Jan 16 '09 at 06:38
0

I've managed to solve the problem. I don't know if it's the best solution but it is a solution.

I set a property called test.type and then use an if statement to determine which target it came from.

<target name="run-unit-tests">  
   <property name="test.executable" value="tools\nunit\nunit-console.exe"/>
   <property name="test.type" value="unit-tests" />
   <call target="do-unit-tests"/>
</target>

<target name="run-unit-tests-teamcity"> 
   <property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>          
   <property name="test.type" value="unit-tests-teamcity" />
   <call target="do-unit-tests"/>
</target>

<target name="do-unit-test">
   <property name="test.assemblies" value="MyProject.dll">
   <call target="do-unit-test-coverage" />
</target>

<target name="do-unit-test-coverage">

   <if test="${test.type=='unit-tests'}">
      <property name="test.args" value="${test.assemblies} ..."/>
   </if>
        
   <if test="${test.type=='unit-tests-teamcity'}">
      <property name="test.args" value="... ${test.assemblies}"/>
   </if>

   <ncover <!--snip -->
           commandLineArgs="${test.args}"
   <!--snip-->
   </ncover>
</target>
Dharman
  • 30,962
  • 25
  • 85
  • 135
mezoid
  • 28,090
  • 37
  • 107
  • 148