46
votes

I'm not very good with Ant, but we're using it as a build tool. Right now, we can run "ant test" and it'll run through all the unit tests.

However, I'd love to be able to do something like ant test some_module and have it accept some_module as a parameter, and only test that.

I haven't been able to find how to pass command line args to Ant - any ideas?

9
I know this question has been out here a while, but if an answer is acceptable to you, please accept it.Kevin McCarpenter

9 Answers

40
votes

One solution might be as follows. (I have a project that does this.)

Have a separate target similar to test with a fileset that restricts the test to one class only. Then pass the name of that class using -D at the ant command line:

ant -Dtest.module=MyClassUnderTest single_test

In the build.xml (highly reduced):

<target name="single_test" depends="compile" description="Run one unit test">
    <junit>
        <batchtest>
            <fileset dir="${test.dir}" includes="**/${test.module}.class" />
        </batchtest>
    </junit>
</target>
9
votes

You can also define a property with an optional default value that can be replaced via command line, e.g.

<target name="test">
  <property name="moduleName" value="default-module" />
  <echo message="Testing Module: ${moduleName}"/>
  ....
</target>

and run it as:

ant test -DmoduleName=ModuleX
6
votes

What about using some conditional in your test target and the specifying -Dcondition=true?

<target name="test" depends="_test, _test_if_true>
   ...
</target> 

<target name="_test_if_true" if="condition">
   ...
</target>

<target name="_test" unless="condition">
   ...
</target>

Adapted a bit from the ant faq.

4
votes

You can define a property on commandline when invoking ant:

ant -Dtest.module=mymodulename

Then you can use it as any other ant property:

...
    <fileset dir="${test.dir}" includes="**/${test.module}.class" />
...

Have a look at Ant's manual.

1
votes

I tried the solutions posted here for the very same original question. Yes just use ant -D<arg_name>. THe -D is a "keyword" I guess. I'm no ant expert and have not read the manuals in detail. Then inside the ant XML files can be accessed like: ${arg_name}

For instance you can have an argument name like: arg.myarg, so in XML ${arg.myarg}.

1
votes

You could try this to access one target at a time. Add these lines to your build.xml file :

<project name="whatever" default="default">
    <input message="Please select module:" addproperty="mod" />
    <target name="default" depends="${mod}/>
...
</project>

This allows you to enter the module you want to execute and execute that itself instead of running the whole build.xml

You might need to make a few more changes to your build.xml for this to work perfectly.

0
votes

Ant really doesn't have parameters_ for the build file. I can think of a few ways to do this:

Use a special target to specify the tests. You can use the <for/> task from AntContrib to allow you to specify multiple tests. You'll need to download the Ant-Contrib jar file. I recommend placing it inside your project under the `${basedir}/antlib/antcontrib" directory. That way, when others checkout your project, they get the needed Ant-Contrib jar file.

<property name="antlib.dir"     value="${basedir}/antlib"/>
<property name="antcontrib.dir" value="${antlib}/antcontrib"/>

<!-- Set up the ant contrib tasks for your use -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
    <classpath>
        <fileset dir="${antcontrib.dir}"/>
    </classpath>
</taskdef>

<target name="select-test"
    description="Select the tests to run"
    depends="test-compile"
    if="junit-tests">
       <for parameter="module" 
          list="${junit-tests}"
          delimiter=" ">
          <sequential>
              <junit
                 fork="true"
                 ...>
                 <batchtest todir="$target/unit-tests">
                 <fileset dir="${test.destdir}">
                    <include name="**/@{module}.class"/>
                 </fileset>
             </junit>
         </sequential>
      </for>
</target>

You cab now run multiple tests like this:

$ ant -D"test-one test-two test-three" select-test
0
votes

For the arguments , there is Facility called property. You need to set the property. As in ANT plain arguments is taken as target name.

0
votes

Lest say you have two modules in your project ModuleX and ModuleY where ModuleX has 2 testcases to run and ModuleY with 10 testcases.

You could do something like this :

ant runTestsOnModule -Dtestmodule="ModuleX" 
       OR to test all modules by calling 
ant tests

<target name="runTestsOnModule">
  <antCall target="testcase${testmodule}"/>
</target>'

<! -- run single module -->
<target name="runTestsOnModule">
  <antCall target="testcase${testmodule}"/>
</target>

<!--run all tests-->    
<target name="tests">
   <antcall target="testcaseModuleX">
   <antcall target="testCaseModuleY">
</target>

<target name="testcaseModuleX">
   ..run junit task to call 2 testcase
</target>

<target name="testcaseModuleY">
  ....run junit task to call 10 testcase
</target>