tags:

views:

4672

answers:

3

Hello Fellow Programmers,

I am having problems running my Junit tests via Ant. I can't seem to get Ant to see the properties file it needs to load a dll my project needs. All my tests work using the Junit GUI in Elcipse, so I'm pretty sure it's not a problem with the tests themselves. I think my problem is something classpath-related, but I can't seem to find the problem.

jar strucure: /root/folder/../Foo.properties

This is how the properties file is loaded in the library:

// load class properties
props = PropertyLoader.loadProperties(Foo.class);

public static Properties loadProperties(Class className) {
    return loadProperties(className.getName());
}

public static Properties loadProperties(final String propsName) {
    Properties props = null;
    InputStream in = null;
    try {
      ClassLoader cl = ClassLoader.getSystemClassLoader();
      String name = propsName.replace('.', '/').concat(".properties");

      in = cl.getResourceAsStream(name);
      if (in != null) {
        props = new Properties();
        props.load(in);
      }
    }
    catch (Exception e) {
      props = null;
    }
    finally {
      if (props == null) {
        System.err.print("Property file " + propsName + " doesn't exist. System terminated.");
        System.exit(0);
      }
    }

    return props;
  }

Except from build file in question:

<!-- Pattern of source files to copy into classpath-->
    <property name="source.files.tocopy"
     value="**/*.properties,**/*.dtd,**/*.xml,**/*.jpg" />

    <path id="compile.classpath">
     <fileset dir="lib">
      <include name="*.jar" />
     </fileset>
    </path>

    <!-- Generate Class-Path entry for the JAR's Manifest -->
    <pathconvert property="manifest.classpath" 
     pathsep=" " dirsep="\">
     <map from="${basedir}/" to="" />
     <fileset dir="lib">
      <include name="*.jar" />
     </fileset>
    </pathconvert>

    <!-- Run tests against the JAR -->
    <path id="test.compile.classpath">
     <path refid="compile.classpath" />
     <pathelement location="${target.jar}" />
    </path>

    <path id="test.classpath">
     <path refid="test.compile.classpath" />
     <pathelement location="${test.classes.dir}" />
    </path>



    <!-- - - - - - - - - - - - - - - - - - 
          target: test-compile                      
         - - - - - - - - - - - - - - - - - -->
    <target name="test-compile" depends="compile, test-init"
     description="Compiles our testing code">

     <javac destdir="${test.classes.dir}"
       debug="true"
       includeAntRuntime="true"
       srcdir="test">
      <classpath refid="test.compile.classpath" />
     </javac>

     <copy todir="${test.classes.dir}">
      <fileset dir="test" includes="${source.files.tocopy}"/>
      <fileset dir="resources" includes="${source.files.tocopy}"/>
     </copy>

    </target>


    <!-- ================================= 
          target: test              
         ================================= -->
    <target name="test" depends="test-compile, optional-tests">

     <description>
      Runs our tests, generates reports, and stops 
      the build on failure.  Optionally runs one test.
     </description>

     <junit printsummary="false" 
      errorProperty="test.failed" 
      failureProperty="test.failed">
      <classpath>
       <path refid="test.classpath" />
      </classpath>   
      <sysproperty key="test.properties" value="${test.properties.file}"/>
      <formatter type="brief" usefile="false" />
      <formatter type="xml" />
      <test name="${testcase}" todir="${test.data.dir}" if="testcase" />
      <batchtest todir="${test.data.dir}" unless="testcase">
       <fileset dir="${test.classes.dir}">
        <patternset>
         <include name="**/test/*Test.class" />
         <exclude name="**/test/*Printer*.class" unless="test.properties.file" />
        </patternset>
       </fileset>
      </batchtest>
     </junit>

I could really use a second set of eyes, so any help is appreciated. Thanks in advance!

--Charly

+2  A: 

Try and use getResource to see which URL is returned in eclipse, and also see if you can get a url to show in the unit test. Maybe you need to pass the name of the actual class file to get that

clazz.getResource(clazz.getName()+".class")

Check that files are copied before you run unit test, so the files are actually placed in the output folder that is used on the classpath when running the unit test.

When eclipse compiles java files, it also copies all non-java files to the output directory automatically. This is why the file is accessible in the classpath in eclipse. If you don't copy non-java files to your build target folder during compile, the properties files will not get copied. It does look from your build files though that you are allready copying the files. Can you verify the same when browsing the folders?

Also, you should not ever use System.exit(0) in your code except for small programs. It's better to have exceptions that propagate to the main function and terminate the program. The reason is that you end up with a library that will terminate the Java process when it's used and fails.

Staale
A: 

The first steps of ant debugging are always:

  1. ant -verbose
  2. ant -debug

Review the output for those targets that relate to the junit tests.

If you find additional information there that solves the problem, great! If not, please edit the question with relevant information from the output.

Ken Gentle
+2  A: 

I have found that in some circumstances the property file if inside the jar cannot be in the root folder. Move it into a directory inside of the jar and then use getResourceAsStream.

Karl

Karl