【问题标题】:How do I run JUnit tests during my Ant build script while omitting test classes from my resulting jar?如何在我的 Ant 构建脚本期间运行 JUnit 测试,同时从生成的 jar 中省略测试类?
【发布时间】:2011-04-10 23:10:18
【问题描述】:

我正在使用 Ant 手册中的 Hello World with 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)

【问题讨论】:

  • 尝试让您的 jar 任务依赖于 junit 任务,以便它在编译之后但在 jar 之前运行测试。
  • 移除junit任务的依赖,它应该依赖于编译任务而不是jar任务。
  • 谢谢,这比教程更有意义并解决了我的问题。如果您编辑答案以反映此信息,我会接受。

标签: java ant build junit jar


【解决方案1】:

你能改变吗:

<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 文件中排除我认为的测试类。

n.b 每个任务的依赖关系的变化。

【讨论】:

  • 即使在添加了缺少的星号 (**/*Test.class) 之后,也无法从我的 .jar 中排除测试文件。我用我尝试过的类似内容编辑了我的原始帖子。
  • 查看上面关于更改任务的依赖属性的内容。
【解决方案2】:

根据@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>

【讨论】:

    猜你喜欢
    • 2017-08-30
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 2012-11-09
    相关资源
    最近更新 更多