Набор тестов JUnit и Ant-сборка «ClassNotFoundException»

#java #eclipse #ant #junit

#java #eclipse #ant #junit

Вопрос:

Я использую Eclipse Indigo. Не уверен, что происходит, но при попытке вызвать набор тестов из сборки ant я получаю ClassNotFoundException. Однако, если я щелкаю правой кнопкой мыши по тестовому классу JUnit и запускаю как Junit Test, тесты выполняются нормально. Ошибка говорит о том, что файл ./test/_ObservableSortUnitTests не найден. Выдает ту же ошибку, даже если я указываю полный путь к файлу.

Вот моя ошибка:

 Buildfile: /home/jason/Dev/ObservableSort/build.xml
Compile:
Test:
    [junit] Testsuite: ./test/_ObservableSortUnitTests
    [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
    [junit]     Caused an ERROR
    [junit] ./test/_ObservableSortUnitTests
    [junit] java.lang.ClassNotFoundException: ./test/_ObservableSortUnitTests
    [junit]     at java.lang.Class.forName0(Native Method)
    [junit]     at java.lang.Class.forName(Class.java:264)
    [junit]     at org.eclipse.ant.internal.launching.remote.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
    [junit]     at org.eclipse.ant.internal.launching.remote.InternalAntRunner.run(InternalAntRunner.java:424)
    [junit]     at org.eclipse.ant.internal.launching.remote.InternalAntRunner.main(InternalAntRunner.java:138)

BUILD FAILED
/home/jason/Dev/ObservableSort/build.xml:75: Test ./test/_ObservableSortUnitTests failed

Total time: 1 second
  

Вот мой ant-скрипт (отказ от ответственности: я очень новичок в ant):

     <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="Build" name="CS 151 Project Build Script" >
    <!--ANT 1.7 is required  -->
    <property name="home" value="." />                
    <property name="src.dir" value = "${home}/src" />
    <property name="dest.dir" value="${home}/Release" />
    <property name="dir.build" value="${home}/lib" />
    <property name="dir.javadoc" value="${dest.dir}/Javadoc" />
    <property name="dir.classes" value="${dest.dir}/Classes" />
    <property name="dir.junit.reports" value="${dest.dir}/Reports" />
    <property name="test.suite.dir" value="${home}/test" />
    <property name="test.suite.class" value ="${test.suite.dir}/_ObservableSortUnitTests" />

    <path id="build.class.path">
        <fileset dir="${dir.build}">
            <include name="*.jar" />
        </fileset>
    </path> 

    <path id="test.class.path">
        <pathelement location="${junit.test.suite}" />
    </path>

    <target name="Clean" description="Deletes all old files">
        <delete dir="${dir.javadoc}" />
        <delete dir="${dir.classes}" />
        <delete dir="${dir.junit.reports}" />
    </target>

    <target name="Prepare" description="Creates all necessary directories">
        <mkdir dir="${dir.javadoc}" />
        <mkdir dir="${dir.classes}" />
        <mkdir dir="${dir.junit.reports}" />
    </target>   

    <target name="Compile">
        <javac srcdir="${src.dir}" destdir="${dir.classes}" includeantruntime="true">
            <classpath refid="build.class.path" />
        </javac>
    </target>

    <target name="Full" description="Executes all build targets">
        <antcall target="Clean" />
        <antcall target="Prepare" />
        <antcall target="Compile" />
        <antcall target="Test" />
        <antcall target="Build" />
        <antcall target="Javadoc" />
        <antcall target="run" />
    </target>

    <target name="Build" description="Creates executable jar" depends="Clean, Prepare, Compile">
        <jar destfile="${dest.dir}/ObservableSort.jar" filesetmanifest="mergewithoutmain">
            <manifest>
                <attribute name="Main-Class" value="cs151.project1.ObservableSortTest"/>
                <attribute name="Class-Path" value="."/>
            </manifest>
            <fileset dir="${home}/bin"/>
        </jar>
    </target>

    <target name="Run" depends="Compile, Build">
        <java jar="${dest.dir}/ObservableSort.jar" fork="true" />
    </target>           

    <target name="Run with Unit Tests" depends="Compile, Build, Test">
        <java jar="${dest.dir}/ObservableSort.jar" fork="true" />
    </target>

    <target name="Javadoc" description="Generate Javadoc" depends="Compile" >
        <javadoc access="public" author="true"  destdir="${dir.javadoc}" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" packagenames="cs151.project1.sorters.insertionsort,cs151.project1.sorters.selectionsort,cs151.project1.Quantifiable,cs151.project1,cs151.project1.sorters.quicksort,cs151.project1.views" source="1.6" sourcepath="${src.dir}" splitindex="false" use="true" version="true"/>
    </target>

    <target name="Test" depends="Compile">
        <junit>
            <classpath refid="build.class.path" />
            <classpath refid="test.class.path" />
            <formatter type="plain" usefile="false" />
            <test name="${test.suite.class}" haltonerror="true" />
        </junit>
    </target>
</project>
  

Ответ №1:

Вы используете путь к классу testsuite вместо полного имени класса.

Несмотря на то, что классы java хранятся в папках файловой системы, Java требует, чтобы вы указывали имя пакета пунктирным, а не косым.

Скорее всего, правильное имя класса test._ObservableSortUnitTests или, может быть _ObservableSortUnitTests

Комментарии:

1. Я попробовал несколько разных перестановок пути к классу и имени файла, которые, на мой взгляд, были бы правильными, но, похоже, мне это просто не нравится.

2. У меня есть класс TestSuite, определенный в ${home}/test, и он содержится внутри (пакет по умолчанию). Есть предложения, что попробовать дальше?

3. Если ваш тест находится в ${home}/test папке, то вам следует добавить его в classpath целевого объекта тестирования. Если тестовый набор находится в пакете по умолчанию, то вам следует указать только classname _ObservableSortUnitTests

Ответ №2:

Если вы укажете имя тестового класса в задаче junit, то вам нужно использовать полное имя класса, как говорит Марк. Из задачи JUnit

 <junit>
  <test name="my.test.TestCase"/>
</junit>
  

Однако, если вы используете пакетный тест, вы можете указать имена файлов, но вам нужно добавить .java в конце:

   <batchtest fork="yes" todir="${reports.tests}">
    <fileset dir="${src.tests}">
      <include name="**/*Test*.java"/>
      <exclude name="**/AllTests.java"/>
    </fileset>
  </batchtest>
  

Комментарии:

1. Это класс TestSuite. У меня есть класс TestSuite, определенный в ${home}/test, и он содержится внутри (пакет по умолчанию). Я перепробовал столько различных возможных комбинаций, которые, на мой взгляд, являются правильными, но ни одна из них не работает. Есть предложения, что попробовать дальше?

Ответ №3:

Глупая ошибка: классы JUnit еще не были скомпилированы.

Решение:

  • Скомпилируйте проект в каталог X
  • Скомпилируйте классы JUnit в каталог Y
  • Добавьте jar-файл JUnit в каталог Z

Внутри тега <test> добавьте каталоги X, Y и Z в classpath.