运行测试时Ant + JUnit = ClassNotFoundExceptions?

时间:2010-04-21 20:12:30

标签: java ant junit

我正在尝试使用JUnit在Ant中运行一些测试,并且我的所有测试都失败了以下的堆栈跟踪:

java.lang.ClassNotFoundException: com.mypackage.MyTestCase

这对我来说没什么意义。我首先使用<javac>编译我的测试用例,然后直接运行<junit>任务来运行测试。我的构建文件如下所示:

<target name="compile.webapp.tests" depends="compile.webapp">
    <javac srcdir="${test.java.src.dir}"
            destdir="${test.java.bin.dir}">
        <classpath>
            <filelist>
                <file name="${red5.home}/red5.jar"/>
                <file name="${red5.home}/boot.jar"/>
                <file name="${bin.dir}/${ant.project.name}.jar"/>
            </filelist>
            <fileset dir="${red5.lib.dir}" includes="**/*"/>
            <fileset dir="${main.java.lib.dir}" includes="**/*"/>
            <fileset dir="${test.java.lib.dir}" includes="**/*"/>
        </classpath>
    </javac>
</target>

<target name="run.webapp.tests" depends="compile.webapp.tests">
    <junit printsummary="true">
        <classpath>
            <filelist>
                <file name="${red5.home}/red5.jar"/>
                <file name="${red5.home}/boot.jar"/>
                <file name="${bin.dir}/${ant.project.name}.jar"/>
            </filelist>
            <fileset dir="${red5.lib.dir}" includes="**/*.jar"/>
            <fileset dir="${main.java.lib.dir}" includes="**/*.jar"/>
            <fileset dir="${test.java.lib.dir}" includes="**/*.jar"/>
            <fileset dir="${test.java.bin.dir}" includes="**/*.class"/>
        </classpath>

        <formatter type="xml"/>

        <batchtest todir="${test.java.output.dir}">
            <fileset dir="${test.java.bin.dir}" includes="**/*TestCase*"/>
        </batchtest>
    </junit>

    <junitreport>
        <fileset dir="${test.java.output.dir}" includes="**/*"/>
        <report todir="${test.java.report.dir}"/>
    </junitreport>
</target>

这真的很奇怪,我似乎无法解决这个问题。我有什么问题吗? 我的项目的目录布局看起来像这样:

${basedir}/src/test/java # this is "test.java.src.dir"
${basedir}/build/test/java # this is "test.java.bin.dir"
${basedir}/lib/main/java # this is "main.java.lib.dir"
${basedir}/lib/test/java # this is "test.java.lib.dir"
${basedir}/build/test/junit # this is "test.java.output.dir"

我的完整构建文件可在此处获取:http://pastebin.com/SVnciGKR
我的属性文件可在此处获取:http://pastebin.com/9LCtNQUq


更新

通过将我的目标修改为如下所示,我能够让事情变得有效。不幸的是,我必须手动将ant-junit.jar和junit.jar嵌入到我的存储库中,但是它可以工作,所以我想这解决了它。如果有人可以帮我摆脱嵌入ant-junit.jar和junit.jar的需要,我真的很感激:

<path id="webapp.tests.path" >
    <pathelement location="${red5.home}/red5.jar"/>
    <pathelement location="${red5.home}/boot.jar"/>
    <pathelement location="${bin.dir}/${ant.project.name}.jar"/>
    <pathelement path="${red5.lib.dir}"/>
    <pathelement path="${main.java.lib.dir}"/>
    <pathelement path="${test.java.lib.dir}"/>
</path>

<target name="compile.webapp.tests" depends="compile.webapp">
    <javac srcdir="${test.java.src.dir}"
            destdir="${test.java.bin.dir}">
        <classpath refid="webapp.tests.path"/>
    </javac>
</target>

<target name="run.webapp.tests" depends="compile.webapp.tests">     
    <junit printsummary="true">
        <classpath>
            <path refid="webapp.tests.path"/>
            <pathelement location="${test.lib.dir}/ant/ant-junit.jar"/>
            <pathelement location="${test.lib.dir}/ant/junit-4.8.2.jar"/>
            <pathelement path="${test.java.bin.dir}"/>
        </classpath>

        <formatter type="xml"/>

        <batchtest todir="${test.java.output.dir}">
            <fileset dir="${test.java.bin.dir}" includes="**/*TestCase*"/>
        </batchtest>
    </junit>

    <junitreport todir="${test.java.report.dir}">
        <fileset dir="${test.java.output.dir}" includes="**/*"/>
        <report todir="${test.java.report.dir}"/>
    </junitreport>

    <delete file="${test.java.report.dir}/TESTS-TestSuites.xml"/>
</target>

如果我没有在类路径中包含jar,我会收到错误,告诉我junit.jar必须在类路径上才能运行<junit>任务。很奇怪,是吗?

3 个答案:

答案 0 :(得分:4)

根据JUnit Task的ANT文档,您必须执行以下选项之一才能运行junit测试,因为对ANT外部的junit.jar存在依赖性:

  

注意:您必须拥有junit.jar   可用。您可以执行以下操作之一:

     
      
  1. 将junit.jar和ant-junit.jar放在ANT_HOME / lib中。
  2.   
  3. 不要将它们放在ANT_HOME / lib中,而是将它们的位置包括在内   您的CLASSPATH环境变量。
  4.   
  5. 使用-lib将两个JAR添加到类路径中。
  6.   
  7. 使用a中的元素指定两个JAR的位置    在构建文件中。
  8.   
  9. 将ant-junit.jar保留在ANT_HOME / lib中的默认位置但包含   junit.jar在传递给   &LT; junit的取代。 (自Ant 1.7起)
  10.   

我已经验证了#1,将junit.jar放在ANT_HOME \ lib中(ant-junit.jar已经存在,ANT 1.8.0)并且我不需要来指定junit JUNIT标记的类路径中的.jar。基本上你选择了#5选项。

答案 1 :(得分:3)

我认为这是问题所在:

<junit printsummary="true">
  <classpath>
    ...
    <fileset dir="${test.java.bin.dir}" includes="**/*.class"/>
  </classpath>

我认为类路径不应该直接包含.class文件,只是bin目录的根目录。

<junit printsummary="true">
  <classpath>
    ...
    <pathelement path="${test.java.bin.dir}"/>
  </classpath>

调试此方法的一个好方法是详细运行构建并仔细检查类路径,以验证它是否设置了您希望如何设置。请参阅Ant command-line options -verbose,可能还有-debug

我很惊讶将classpath设置为仅包含filesetfile元素,而不是pathelement s。请查看Path-like Structures上的Ant手册,了解我的意思。

最后,javacjunit中的类路径之间的重复可能会在将来引发问题。您可能希望命名某些路径或路径集合,因此您不会复制它们。请参阅References上的Ant手册。

答案 2 :(得分:0)

您需要在junit任务类路径中引用$ {test.java.bin.dir}。

编辑:嗯,如果“仍然失败”你的意思是同样的错误,那么我的下一个猜测是必须弄清楚根目录相对于包的起始位置,但我需要了解更多关于你的目录结构,以确保。