代码之家  ›  专栏  ›  技术社区  ›  Redwood

如何在Ant构建脚本期间运行JUnit测试,同时从生成的JAR中省略测试类?

  •  4
  • Redwood  · 技术社区  · 14 年前

    我正在使用Ant手册中的Hello World和Ant教程来学习Ant。

    教程的最后一部分涉及到将JUnit测试添加到项目中。

    我已经完成了教程中描述的所有工作,现在要做一些小的更改。

    我想做的一个更改是在典型的构建过程中运行测试,但不要让*test.class文件最终出现在应用程序的最后一个.jar文件中。这是因为,我将要完成的最终项目将是一个具有有限硬盘空间的设备,只支持Java SDK的一个子集,所以我宁愿完全从JAR中省略这些测试文件。

    我该怎么做?

    创建两个独立的jar就足够简单了,一个用于测试,一个用于部署,但这似乎不太理想。

    下面是我当前的build.xml文件。

    <property name="src.dir"     value="src"/>
    
    <property name="build.dir"   value="build"/>
    <property name="classes.dir" value="${build.dir}/classes"/>
    <property name="jar.dir"     value="${build.dir}/jar"/>
    <property name="lib.dir"     value="lib"/>
    <property name="report.dir"  value="${build.dir}/junitreport"/>
    
    
    <property name="main-class"  value="oata.HelloWorld"/>
    
    <path id="classpath">
        <fileset dir="${lib.dir}" includes="**/*.jar"/>
        <path location="[LocalPath]/junit-4.8.2.jar"/>
    </path>
    
    <path id="application" location="${jar.dir}/${ant.project.name}.jar"/>
    
    <target name="clean">
        <delete dir="${build.dir}"/>
    </target>
    
    <target name="compile">
        <mkdir dir="${classes.dir}"/>
        <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
        <copy todir="${classes.dir}">
            <fileset dir="${src.dir}" excludes="**/*.java"/>
        </copy>
    </target>
    
    <target name="jar" depends="compile">
        <mkdir dir="${jar.dir}"/>
        <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
            <manifest>
                <attribute name="Main-Class" value="${main-class}"/>
            </manifest>
        </jar>
    </target>
    
     <target name="junit" depends="jar">
         <mkdir dir="${report.dir}"/>
         <junit printsummary="yes" haltonfailure="yes" showoutput="yes">
            <classpath>
                <path refid="classpath"/>
                <path refid="application"/>
            </classpath>
    
            <formatter type="xml"/>
    
            <batchtest fork="yes">
                <fileset dir="${src.dir}" includes="*Test.java"/>
            </batchtest>
        </junit>
    </target>
    
    <target name="junitreport" depends="junit">
        <junitreport todir="${report.dir}">
            <fileset dir="${report.dir}" includes="TEST-*.xml"/>
            <report todir="${report.dir}"/>
        </junitreport>
    </target>
    
    <target name="run" depends="junit">
        <java fork="true" classname="${main-class}">
            <classpath>
                <path refid="classpath"/>
                <path refid="application"/>
            </classpath>
        </java>
    </target>
    
    <target name="clean-build" depends="clean,junit"/>
    
    <target name="main" depends="clean,run"/>
    

    我尝试过的一件事是修改jar命令以排除*test.class文件

    ...
    <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}" excludes="**/*Test.class">
    ...
    

    它成功地排除了测试类,但是当通过JUnit目标运行测试时,当用以下堆栈跟踪运行时,它将失败 -v :

    [LocalPath]\build.xml:44: Test HelloWorldTest failed
            at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.actOnTestResult(JUnitTask.java:1863)
            at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:814)
            at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.executeOrQueue(JUnitTask.java:1808)
            at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:760)
            at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
            at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:597)
            at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
            at org.apache.tools.ant.Task.perform(Task.java:348)
            at org.apache.tools.ant.Target.execute(Target.java:390)
            at org.apache.tools.ant.Target.performTasks(Target.java:411)
            at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1397)
            at org.apache.tools.ant.Project.executeTarget(Project.java:1366)
            at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
            at org.apache.tools.ant.Project.executeTargets(Project.java:1249)
            at org.apache.tools.ant.Main.runBuild(Main.java:801)
            at org.apache.tools.ant.Main.startAnt(Main.java:218)
            at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
            at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
    
    2 回复  |  直到 14 年前
        1
  •  4
  •   Jonathan Holloway    14 年前

    你能改变吗?

    <target name="jar" depends="compile">
        <mkdir dir="${jar.dir}"/>
        <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
            <manifest>
                <attribute name="Main-Class" value="${main-class}"/>
            </manifest>
        </jar>
    </target>
    

    到:

    <target name="jar" depends="junit">
        <mkdir dir="${jar.dir}"/>
        <jar destfile="${jar.dir}/${ant.project.name}.jar">
            <fileset dir="${classes.dir}" excludes="**/*Test.class"/>
            <manifest>
                <attribute name="Main-Class" value="${main-class}"/>
            </manifest>
        </jar>
    </target>
    
     <target name="junit" depends="compile">
         <mkdir dir="${report.dir}"/>
         <junit printsummary="yes" haltonfailure="yes" showoutput="yes">
            <classpath>
                <path refid="classpath"/>
                <path refid="application"/>
            </classpath>
    
            <formatter type="xml"/>
    
            <batchtest fork="yes">
                <fileset dir="${src.dir}" includes="*Test.java"/>
            </batchtest>
        </junit>
    </target>
    

    这应该从最终的JAR文件中排除我相信的测试类。

    注意:每个任务的依赖性变化。

        2
  •  2
  •   Redwood    14 年前

    根据@jon的建议,我将junit目标更改为针对build/classes文件夹而不是jar运行,并相应地更新了依赖项。

    我更新的build.xml文件如下:

    <project name="HelloWorld" basedir="." default="main">
    
        <property name="src.dir"     value="src"/>
    
        <property name="build.dir"   value="build"/>
        <property name="classes.dir" value="${build.dir}/classes"/>
        <property name="jar.dir"     value="${build.dir}/jar"/>
        <property name="lib.dir"     value="lib"/>
        <property name="report.dir"  value="${build.dir}/junitreport"/>
    
        <property name="main-class"  value="oata.HelloWorld"/>
    
        <path id="classpath">
            <fileset dir="${lib.dir}" includes="**/*.jar"/>
            <path location="[LocalPath]/junit-4.8.2.jar"/>
        </path>
    
        <path id="application" location="${jar.dir}/${ant.project.name}.jar"/>
    
        <target name="clean">
            <delete dir="${build.dir}"/>
        </target>
    
        <target name="compile">
            <mkdir dir="${classes.dir}"/>
            <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
            <copy todir="${classes.dir}">
                <fileset dir="${src.dir}" excludes="**/*.java"/>
            </copy>
        </target>
    
        <target name="jar" depends="junit">
            <mkdir dir="${jar.dir}"/>
            <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}" excludes="**/*Test.class">
                <manifest>
                    <attribute name="Main-Class" value="${main-class}"/>
                </manifest>
            </jar>
        </target>
    
        <target name="junit" depends="compile">
            <mkdir dir="${report.dir}"/>
            <junit printsummary="yes" haltonfailure="yes" showoutput="yes">
                <classpath>
                    <path refid="classpath"/>
                    <path location="${classes.dir}"/>
                </classpath>
    
                <formatter type="xml"/>
    
                <batchtest fork="yes">
                    <fileset dir="${src.dir}" includes="*Test.java"/>
                </batchtest>
            </junit>
        </target>
    
        <target name="junitreport" depends="junit">
            <junitreport todir="${report.dir}">
                <fileset dir="${report.dir}" includes="TEST-*.xml"/>
                <report todir="${report.dir}"/>
            </junitreport>
        </target>
    
        <target name="run" depends="jar">
            <java fork="true" classname="${main-class}">
                <classpath>
                    <path refid="classpath"/>
                    <path refid="application"/>
                </classpath>
            </java>
        </target>
    
        <target name="clean-build" depends="clean,jar"/>
    
        <target name="main" depends="clean,run"/>
    
    </project>