tags:

views:

228

answers:

3

[Edit] Solved, small mistake done by me being an ant beginner. In the test target, it needs to be <classpath refid="my.classpath"/> instead of <classpath id="my.classpath"/>. That obviously overwrote my defined classpath property. That makes it clear that ant is not able to find the library. Note to me: rtfm![/Edit]

First things first: I'm using Ant 1.7.1 and JUnit 4.7.

This bothers me for quite a fewhours now. I've got a Netbeans project (6.7.1). In the project I added test sources, now I would like to do invoke the testing from ant. So I've got the following ant file:

<?xml version="1.0" encoding="UTF-8"?>

<project name="LiveStreamClient" default="clean-build" basedir=".">
<description>Builds, tests, and runs the project.</description>
<property name="src.dir"        value="src"/>
<property name="build.dir"      value="build"/>
<property name="classes.dir"    value="${build.dir}/classes"/>
<property name="test.classes.dir" value="${build.dir}/classes/livestreamclient"/>
<property name="jar.dir"        value="${build.dir}/jar"/>    
<property name="report.dir"     value="${build.dir}/junitreport"/>
<property name="lib.dir"        value="lib"/>
<property name="test.dir"       value="test"/>

<property name="main.class"     value="livestreamclient.Main"/>
<property name="VERSION"        value="0.1."/>

<path id="my.classpath">
    <fileset dir="${lib.dir}" includes="**/*.jar"/>
    <pathelement location="${classes.dir}"/>
   <!-- <pathelement location="${test.classes.dir}" />
    <pathelement location="${test.dir}" /> -->
</path>

<!-- increment the build number -->    
<buildnumber/>

<!-- clean deletes complete build directory -->
<target name="clean">
    <delete dir="${build.dir}"/>
</target>

<!-- compile classes -->
<target name="compile">
    <mkdir dir="${classes.dir}"/>
    <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
    <!-- <javac srcdir="${test.dir}" destdir="${classes.dir}"/> -->
</target>

<!-- pack as java archive -->
<target name="jar" depends="compile">
    <mkdir dir="${jar.dir}"/>
    <jar destfile="${jar.dir}/${ant.project.name}${VERSION}${build.number}.jar" basedir="${classes.dir}">
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
</target>

<!-- run the test classes -->    
<target name="test" depends="jar">
    <mkdir dir="${report.dir}"/>
    <junit printsummary="yes">
        <classpath id="my.classpath"/>
        <formatter type="plain"/>
        <batchtest fork="yes" todir="${report.dir}">
            <fileset dir="${test.dir}">
                <include name="**/*Test*"/>
            </fileset>
        </batchtest>
    </junit> 
</target>

<!-- JUnit testing report -->    
<target name="junitreport">
    <junitreport todir="${report.dir}">
        <fileset dir="${report.dir}" includes="Test-*.xml"/>
        <report todir="${report.dir}"/>
    </junitreport>
</target>

<!-- run the jar -->
<target name="run" depends="jar">
    <java jar="${jar.dir}/${ant.project.name}${VERSION}${build.number}.jar" fork="true"/>
</target>

<target name="commit" depends="run">
  <exec executable="hg">
    <arg value="ci"/>
    <arg value="-m"/>
    <arg value="TESTCOMMIT"/>
  </exec>
</target>


<!-- default target -->
<target name="clean-build" depends="clean,jar"/>

<target name="main" depends="clean,run"/>

My approach is to batchtest the (more to come) testfiles in the test.dir folder, which holds only the following test class so far:

package livestreamclient.modeltest;

import org.junit.*;
import static org.junit.Assert.*;
import livestreamclient.model.*;

public class LiveStreamModelTest {
    @Test
    public void testCreation() {
        LiveStreamModel model = new LiveStreamModel();
        assertFalse(1 == 2);
    }

}

The test file resides in the test folder, whereas the actual source is within the src folder, as that is how NetBeans handles the structure by default.

Ant gives me ClassDefNotFoundException for the test file in the JUnit task... But the class is in the desired folder. Am I missing something conceptionally here?

EDIT:

The exception trace created in the junit report is the following:

Testsuite: livestreamclient.modeltest.LiveStreamModelTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec

Caused an ERROR
livestreamclient.modeltest.LiveStreamModelTest
java.lang.ClassNotFoundException: livestreamclient.modeltest.LiveStreamModelTest
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
+2  A: 

A ClassDefNotFoundError means that the classloader can load a class X but cannot instantiate it because it cannot load the classes that class X depends on.

So, in your case, check that JUnit 4's JAR (the classes LiveStreamModelTest depends on) is really on the classpath when running tests. Also check that you are using Ant 1.7+ (which is required for JUnit 4 AFAIK).

Pascal Thivent
Thanks, this helped me to narrow it down. I'm a beginner using ant, so I made a little mistake... see how I (not) referenced my classpath saying <classpath id="..."/>. It needs to be <classpath refid=".."/> of course. Bummer. I obviously overwrote my own definition with an empty classpath entry and therefore ant could not find the JUnit jar. Thanks for all your hints, guys!
rdoubleui
A: 

Try adding the JUnit 4 JAR to your Ant /lib directory.

duffymo
That might work, however I wanted to add the junit jar locally and "ship" it with the project, so somebody else who wants test the project, doesn't have to rely on this dependency. Is this rather an uncommon thing to do?
rdoubleui
I think it is uncommon, but that doesn't mean undesirable. It sounds like Pascal has sorted you out. Good luck.
duffymo
+1  A: 

It's also possible that there is something wrong with the test class itself; for example if there is an exception thrown in a static initializer the you will get a ClassDefNotFoundError. Try to verify through some other means (debugger, test code) that the class is working as expected.

Ken Liu
I ran the test class from within NetBeans, it works. So I think it must be some issue about how I included the junit jar in the build.xml, as Pascal Thivent stated.
rdoubleui