invoking only the required test in testng file while using ant - ant

I am trying to invoke tests of a testng.xml file from ant.
My testng.xml looks like the following:
<suite name="testsuite">
bunch of parameters here
<test name="test1">
</test>
<test name="test2">
</test>
</suite>
Now, I want to run only the "test1" tests and not those of "test2". Is there a way (parameter?) to tell the ant build.xml file to do this?
<testng classpathref="testng.class.path" delegateCommandSystemProperties="true"
outputDir="${test-output}" haltOnfailure="false" useDefaultListeners="true"
parallel="methods"
failureproperty="test.failure">
<xmlfileset file="testng.xml"/>
<!--forked JVM OOM issue-->
<jvmarg value="-Xmx512M"/>
<jvmarg value="-Xms512M"/>
<jvmarg value="-Xmn192M"/>
<jvmarg value="-XX:PermSize=128M"/>
<jvmarg value="-XX:MaxPermSize=128M"/>
</testng>

Look up -testnames in the documentation (note: plural).

The xml files are there for exacly that: not running all tests from a class file containing tests. As I see it, the intended way to go would be to change the existing xml file, or create a new one.
Still, if your tests are included in different class files (I cannot see this from your example code), you could specify a classfileset instead of an xmlfileset, e.g.:
<testng workingDir="../../" outputdir="${output_dir}"
verbose="2" listeners="org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter"
classpathref="testsClasspath">
<classfileset dir="./${test_classes}/com/my/organization" includes="MyTest.class" />
</testng>

Related

Failed to create task or type testng

I am trying to run my testng project created in eclipse through ant. Getting below error:
Failed to create task or type testng. Name is undefined... here is the snippet:
<testng classpath="${test.classpath}:${test.dest}" suitename="suite">
<xmlfileset dir="${ws.home}" includes="testng.xml"/>
</testng>
</target>
I also tried to add testng task but then nothing happens.
Please help!...
You can find more around here: http://testng.org/doc/ant.html
Basically, you need to have a taskdef tag like:
<taskdef resource="testngtasks" classpath="path/to/testng.jar"/>
The testng task you wrote appears to be fine.
You need to add the TestNG tasks to Ant
<taskdef resource="testngtasks" classpath="${extralib.dir}/testng5.13.1.jar" />

Running PigUnit in a subdirectory with Ant

My problem is with running PigUnit via ant from a parent directory.
I am using the PigUnit example straight off of the PigUnit site.
The ant script I am using is here:
<junit printsummary="on" fork="true" haltonfailure="yes">
<jvmarg value="-Duser.dir=${basedir}"/>
<classpath refid="junit.class.path" />
<formatter type="xml" />
<batchtest todir="${test.report.dir}">
<fileset dir="${test.dir}">
<include name="**/*Test*.java" />
</fileset>
</batchtest>
</junit>
</target>
This script works perfectly fine if I run ant in the working directory of the project. However, when I remotely call the script with this line of code in an ant build script in the Pig project's parent directory
<ant dir="${pig.dir}" target="main" inheritall="false" antfile="build.xml"/>
I get a FileNotFoundException:
java.io.FileNotFoundException">java.io.FileNotFoundException: top_queries.pig (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at org.apache.pig.pigunit.PigTest.readFile(PigTest.java:273)
at org.apache.pig.pigunit.PigTest.readFile(PigTest.java:269)
at org.apache.pig.pigunit.PigTest.<init>(PigTest.java:92)
at TopQueriesTest.testTop2Queries(Unknown Source)
This same FNF exception also happens if I run ant from the command line in the parent directory:
ant -f PigJavaTest/build.xml junit
My workaround to helping PigUnit find top_queries.pig file to specifiy the top_queries.pig file's location relative to the Pig project's parent directory, e.g.
PigTest test = new PigTest("PigTestJava/top_queries.pig", args);
but this is not optimal because it breaks when running ant from a directory different from the parent one.
Other JUnit tests will run normally from the parent directory, but PigUnit always throws the same FNF exception. I also tried doing a simple test with PigServer (loading/dumping a file) and the PigServer test behaved just like PigUnit had.
Why does this FileNotFoundException get thrown when calling ant from the parent directory, and how can I fix it?
You have a relative path to your pig file. So if you call the ant script from the working directory of the project it should work. When you call the ant script from the parent project, the relative path now is relative to the parent directory.
http://ant.apache.org/manual/Tasks/ant.html
when you call the ant task here, you are correctly setting the dir property, but that only changes the value of ${basedir} property for the follow in script, not the actual working directory when the junit task runs.
I suggest you use the dir attribute in your junit task to hard set the working directory (i guess that's what you're trying to do with the jvmarg option):
<junit printsummary="on" fork="true" haltonfailure="yes" dir="${basedir}">
<jvmarg value="-Duser.dir=${basedir}"/>
<classpath refid="junit.class.path" />
<formatter type="xml" />
<batchtest todir="${test.report.dir}">
<fileset dir="${test.dir}">
<include name="**/*Test*.java" />
</fileset>
</batchtest>
</junit>
See http://ant.apache.org/manual/Tasks/junit.html for more details

What are consequences of specifying different listeners in different parts of TestNG configuration?

Problem description:
The setup is executing Ant build script with TestNG target, which then loads testng.xml file. There is a possibility to specify listeners in both Ant file and testng.xml.
The questions arising are following:
Will both set up ways be supported? Will all the listeners specified in both configuration location be used during test execution?
Will any of listeners be prioritized over another? If yes, how?
Sample set up:
Ant file:
<project>
<property name="classes.dir" path="<my_classes_dir>" />
<property name="test.dir" path="<my_test_dir>" />
<target name="run-test">
<testng useDefaultListeners="false"
listeners="org.testng.reporters.EmailableReporter, org.testng.reporters.XMLReporter, com.example.MyCustomReporter">
<classpath>
<path path="${classes.dir}" />
</classpath>
<xmlfileset dir="${test.dir}" includes="testng.xml" />
</testng>
</target>
</project>
TestNG.xml:
<suite name="MyTestSuite">
<listeners>
<listener class-name="com.example.MyListener" />
<listener class-name="org.testng.reporters.FailedReporter" />
</listeners>
<test name="MyTest1">
<classes>
<class name="com.example.MyTest1" />
</classes>
</test>
</suite>
Background:
I have to support existing project which uses set up similar to the one described above. The Ant build file disables default reporters. Without touching Ant build file, I would like to specify additional report listeners (FailedReporter and/or any custom ones) for my tests in testng.xml.
I believe all listeners should be run, in your build file as well as in your testng.xml.
The testng.xml listeners would be executed second.
If the same listener is listed in both, build file and testng.xml, it would be executed twice.
This is based on my experience with Maven, but I guess, with ant it should be the same.
Also the order of listeners specified in testng.xml cannot be guaranteed in case both are implementing the same set of interfaces.
Hope it helps.

Relative path problem in ANT junit task

I have setup an ant script as eclipse builder to automatically run all my tests, like below:
<project name="auto-test" default="test">
<property name="tst-dir" location="C:\STAF\services\custom\TopCoder\bin" />
<path id="classpath.base" />
<path id="classpath.test">
<pathelement location="D:\eclipse\eclipse\plugins\org.junit4_4.3.1\junit.jar" />
<pathelement location="${tst-dir}" />
<path refid="classpath.base" />
</path>
<target name="test" description="Run the tests">
<junit>
<classpath refid="classpath.test" />
<formatter type="brief" usefile="false" />
<test name="testDataGenerator.test.AllTests" />
</junit>
</target>
</project>
It was all good before I changed a test fixture file from absolute path to relative path:
SAXReader reader = new SAXReader();
Document document = reader.read(new File(".").getCanonicalPath()+"\\conf\\TestData.xml");
The ant task now try to open D:\eclipse\eclipse\conf\TestData.xml, instead of C:\STAF\services\custom\TopCoder\conf\TestData.xml, I've also try to run AllTests manually from Eclipse and it's all good.
Has anyone met similar problem before?
Thanks in advance.
PS. ANT_HOME=D:\eclipse\eclipse\plugins\org.apache.ant_1.7.0.v200706080842
Follow up:
I tried to run the ant script from command line, and find below:
C:\STAF\services\custom\TopCoder>ant -f c:\STAF\services\custom\TopCoder\task\build.xml, the ant script works correctly.
C:>ant -f c:\STAF\services\custom\TopCoder\task\build.xml, the script will claim: [junit] C:\conf\TestData.xml (The system cannot find the path specified)
I've also checked eclipse builder setting, there seems nothing to change the path to D:\eclipse\eclipse.
Java resolves relative paths against the current user directory, which is typically the directory from where the java program was invoked.
One way to overcome this issue is to define an environmental variable for your base path. Then, you could easily use "relative paths" (meaning, create absolute paths by concatenating the base path and the relative path).
Here is the solution I find:
Just as kgiannakakis mentioned, Ant also start executing its task from the location it was invoked, so we just need to change the working directory setting of our custom eclipse builder.
In the JRE tab, choose "Execution Environment".
Change the Working directory to your current workspace.
Looks like I've missed the karma but anyway...
We do this:-
Build.xml
<project name="whatever">
<property file="build.${env.COMPUTERNAME}.properties"/>
<property file="build.properties"/>
build.properties
project.root=..
build.file.dir=${project.root}/buildfiles
deploy.dir=${project.root}/deploy
which of course you can override by creating your OWN build.computername.properties to allow for developer path differences etc

How do I pass an argument to an Ant task?

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?
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>
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
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.
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.
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}.
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
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.
For the arguments , there is Facility called property. You need to set the property. As in ANT plain arguments is taken as target name.
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>

Resources