Why won't ant run my unit tests correctly? - ant

I'm trying to figure out how to set up a project using ant. For some reason, I can't get the junit tests to run. I set up a simple dummy project using ant to try and figure this out. All it has is a single unit test that should pass trivially.
My project structure looks like this.
.
|-- build.xml
|-- src
`-- test
|-- foo
| `-- MainTest.java
`-- junit-4.10.jar
MainTest.java looks like this.
package foo;
import org.junit.*;
import static org.junit.Assert.*;
public class MainTest {
#Test
public void passes() {
System.out.println("It works!");
}
}
And here is build.xml.
<project name="Nes" default="build" basedir=".">
<target name="build-test">
<javac srcdir="test">
<classpath>
<pathelement location="test/junit-4.10.jar" />
</classpath>
</javac>
</target>
<target name="test" depends="build-test">
<junit>
<classpath>
<pathelement location="test/junit-4.10.jar" />
</classpath>
<batchtest>
<fileset dir="test" includes="foo/MainTest.class" />
</batchtest>
</junit>
</target>
</project>
Here's the output I get from running ant test.
Buildfile: /home/hayden/dev/nes/build.xml
build-test:
[javac] /home/hayden/dev/nes/build.xml:4: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
test:
[junit] Test foo.MainTest FAILED
BUILD SUCCESSFUL
Total time: 0 seconds
I'm running ant 1.8.2 and Java 6.
What am I doing wrong?

You need to add a path to the actual .class file so JUnit can actually run the test. Since you are fully qualifying the test class name, you need to include the directory that contains the foo package:
<target name="test" depends="build-test">
<junit>
<classpath>
<pathelement location="test/junit-4.10.jar" />
<pathelement location="test" />
</classpath>
But I'd recommend that you change the javac task to not output build artifacts (i.e. .class files) into the same directory as your source files. Create a top-level "build" directory and put all your build output in there.
You should also quiet the first warning by adding a includeantruntime attribute to the javac task:
<javac srcdir="test" includeantruntime="false">

Related

How to run a Junit file in build.xml

I need to run a junit file from ant build.xml, where junit resides in testscripts package and junit class has been extended by other class which resides in another package called supportlibraries ,
now to how to run my junit through build.xml
can any help me out
Thanks
In addition to what Mark O'Connor suggested, you need to set up your dependencies in your junit task.
<junit ....>
<classpath>
<pathelement path="testscripts" />
<pathelement path="supportlibraries">
<!-- Add other dependencies here. -->
</classpath>
<test name ="...">
</test>
</junit>

Ant build script not seeing refid

I have a build.xml file that includes a common.xml file that defines some refid values. However, my task cannot see the refid value. I have not been able to find a solution on the web and am looking for some help.
I call the genbeans target in the build.xml file. It fails on the xmlbean taskdef with the message Reference my_classpath_jars not found.
build.xml
----------------------------
[includes common.xml]
**my_classpath_jars fails to be seen at this point - defined in common.xml**
<taskdef name="xmlbean" classname="org.apache.xmlbeans.impl.tool.XMLBean">
<classpath refid="my_classpath_jars"/>
</taskdef>
<!-- Generate the XMLBeans java code from our source XSD file(s) -->
<target name="genbeans" description="Generate XML Bean files" depends="build_my_jar_cpath">
<mkdir dir="${lib}"/>
<xmlbean destfile="${lib}/${appname}Beans.jar" failonerror="true">
<classpath refid="my_classpath_jars"/>
<fileset dir="src/XSD Files" includes="*.xsd, *.wsdl"/>
</xmlbean>
</target>
common.xml
-----------------------------
<target name="build_my_jar_cpath">
<path id="my_classpath_jars">
<fileset dir="${jardir}" includes="**/*.jar" />
</path>
<pathconvert pathsep="${path.separator}" property="myjar.clpath" refid="my_classpath_jars"/>
</target>
When in doubt, use the ant -d switch when calling your target. You'll see a ton of output. Save it to a file and parse through it.
Do that, and the first thing you'll notice in the output is that it's defining your taskdefbefore you have defined your my_classpath_jars. That my_classpath_jars refid is only set when you call that greenbeans target. Your <taskdef> is executed before any of your targets are called.
Either take the definition of my_classpath_jars out of the target greenbeans, or put your <taskdef> in there.

Intermodule dependency in ant

I am using Ant 1.8
I have multiple modules in intelliJ IDEA. Each module has a build.xml and currently i need to browse till build.xml of that file and run ant for every module.
e.g. module B's build success depends on whether module A's build was successful.
Now, i want to update this process. It will be great if an option exists wherein i can write a single build process which will first build distribution for module A and then while building distribution for B, it will be checked if build for module A is successful.
Is there any way using current Ant mechanism. i could see something similar in ivy but i cant use it in my project.
Please suggest an approach using basic Ant features.
The subant task in ANT is the most flexible way to invoke a multi-module build, for example:
<project name="parent" default="build">
<target name="build">
<subant>
<filelist dir=".">
<file name="moduleA/build.xml"/>
<file name="moduleB/build.xml"/>
</filelist>
<target name="clean"/>
<target name="build"/>
</subant>
</target>
</project>
Project structure
|-- build.xml
|-- moduleA
| `-- build.xml
`-- moduleB
`-- build.xml
Note:
In my opinion the most powerful way to use this task is to combine it with the buildlist task from Apache ivy. Let the ivy inter-module dependency declarations automatically determine the module build order.
Thanks Mark!!
Your answer helped me a lot.
In addition to above answer I would like to add details, if properties are being loaded from properties file.
Project Structure:
|-- build.xml
|-- ProjectOne
-- build.xml
-- antbuilds.properties
|-- ProjectTwo
-- build.xml
-- antbuilds.properties
Common ANT build file:
<project name="Parent" default="all">
<target name="ProjectOne">
<subant>
<property file="ProjectOne/antbuilds.properties"/>
<filelist dir=".">
<file name="ProjectOne/build.xml"/>
</filelist>
<target name="deploy"/>
</subant>
</target>
<target name="ProjectTwo">
<subant>
<property file="ProjectTwo/antbuilds.properties"/>
<filelist dir=".">
<file name="ProjectTwo/build.xml"/>
</filelist>
<target name="deploy"/>
</subant>
</target>
<target name="all" depends="ProjectOne, ProjectTwo">
</target>

Making jUnit output info and compile to /build folder

I have the following Ant buildfile:
<?xml version="1.0"?>
<!-- the value of the default attr must be one of the targets. -->
<project name="Money" default="build-source" basedir=".">
<description>The Money project build file.</description>
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="junit" location="lib/junit-4.9b3.jar"/>
<path id="_classpath">
<pathelement path="${junit}"/>
<pathelement path="${build}"/>
</path>
<target name="prepare">
<mkdir dir="${build}"/>
</target>
<target name="build-source" depends="prepare"
description="compile the source ">
<javac srcdir="${src}" destdir="${build}">
<classpath refid="_classpath"/>
</javac>
</target>
<target name="run" depends="build-source">
<junit printsummary="on" showoutput="on">
<test name="money.MoneyTest"/>
<classpath refid="_classpath"/>
</junit>
</target>
</project>
It's pretty basic - I'm just trying to get this thing to run properly. What I don't get is: 1) Why does it output the compiled files to a /build/money directory? I want the output directory to be just /build, given this directory structure for my files:
build/
build.xml
lib/
src/
test/
2) When there are tests that don't pass, it says "Test money.MoneyTest FAILED". I'd like it to output info about the failure, expected / actual values, line number, etc.
I can't figure this out by staring at the buildfile above. Any advice?
It outputs the compiled files under build, creating a directory structure that corresponds to the layout of your packages.
Since you put your classes in the money package, the output will be under build/money. If you put your classes under a org.example.foo package, your output would be in the build/org/example/foo directory.
To have your .class files in build, you would have to use the default package.
Edit
I assume your source files have a package money; declaration, as in:
package money;
public class MoneyTest {
...
}
If you add a <formatter> element, detailed reports about test failures will be written to an output file (by default, named TEST-name). See also the Ant Junit Task Documentation.
<junit printsummary="withOutAndErr" showoutput="on">
<formatter type="plain"/>
<test name="money.MoneyTest"/>
<classpath refid="_classpath"/>
</junit>
I have not found a way to directly print the failed tests reports to standard output.

Ant fails to find junit for project generated with wsdl2java

I created a axis2 soap client project with unit tests using the following command:
wsdl2java -t -uri http://myDomain.tld/myService.svc?wsdl
I then ran ant and got build errors because it could not find junit methods such as fail(),assertNotNull(), etc. I realize I need the compiler to reference a junit jar. Looking in the build.xml I see the following:
<property name="classes" value="${build}/classes"/>
<property name="lib" value="${build}/lib"/>
So I place junit-4.8.2.jar in the build.lib subfolder. I still get the same errors. What else do I need to do to get ant to build my project?
Update:
I made the following changes to the build.xml:
Added the lib folder as a path with the id local.class.path
<path id="local.class.path">
<fileset dir="${lib}">
<include name="*.jar"/>
</fileset>
</path>
Then I modified my init task to look for junit:
<available classpathref="local.class.path" property="junit.available" classname="junit.framework.TestCase"/>
<condition property="jars.ok">
<and>
<isset property="stax.available"/>
<isset property="axis2.available"/>
<isset property="junit.available"/>
</and>
</condition>
<!--Print out the availabilities-->
<echo message="Stax Availability= ${stax.available}"/>
<echo message="Axis2 Availability= ${axis2.available}"/>
<echo message="JUnit Availability= ${junit.available}"/>
And strangely the output is:
H:\Code\Java\test.axis2> ant pre.compile.test
Buildfile: H:\Code\Java\RiskTools.axis2\build.xml
init:
[mkdir] Created dir: H:\Code\Java\test.axis2\build
[mkdir] Created dir: H:\Code\Java\test.axis2\build\classes
[mkdir] Created dir: H:\Code\Java\test.axis2\build\lib
pre.compile.test:
[echo] Stax Availability= true
[echo] Axis2 Availability= true
[echo] JUnit Availability= ${junit.available}
BUILD SUCCESSFUL
Total time: 0 seconds
So it seems I am doing something wrong due to the line [echo] JUnit Availability= ${junit.available}
Apparently build/lib is the transient folder that gets blown away by ant clean. I made a folder called lib at the project root and then did the following to the build.xml.
In the root I added <property name="dep_libs" value="${project.base.dir}/lib"/>
I then change my path statement above to:
<path id="local.class.path">
<fileset dir="${dep_libs}">
<include name="*.jar"/>
</fileset>
</path>
Then everything worked.

Resources