【问题标题】:Junit/Ant re-run failed testsJunit/Ant 重新运行失败的测试
【发布时间】:2011-12-05 13:26:30
【问题描述】:

我想知道是否有人知道如何在同一次运行中重新运行失败的 Junit 测试。例如,测试 1-5 运行并全部通过,然后当测试 6 运行时,它第一次失败。然后它会自动再次运行第二次,然后继续进行测试 7。我正在使用一个运行我所有测试的 ant 脚本。 如果有帮助的话,测试将在 Hudson 盒子上运行。我读到了能够选择失败的测试并将它们放入一个新文件中,在第二次运行套装时运行它们,但这并不是我真正想要的。

任何正确方向的帮助或指示都会有所帮助。谢谢。

<!-- ============================= -->
<!--   target: test-regression-all -->
<!-- ============================= -->
<!--
<target name="test-regression-all" description="Runs all tests tagged as regression" depends="compile">
    <mkdir dir="${target.reports.dir}"/>
    <junit printsummary="yes" haltonerror="no" haltonfailure="no" fork="yes"
               failureproperty="junit.failure" errorproperty="junit.error" showoutput="true">           
        <formatter type="xml"/>
        <classpath>
            <pathelement location="${target.build.classes.dir}"/>
            <path refid="classpath"/>
        </classpath>
        <batchtest todir="${target.reports.dir}">
           <fileset dir="${src.dir}">
              <include name="emailMarketing/AssetLibrary/*.java" />
              <include name="emailMarketing/attributes/*.java" />
              <include name="emailMarketing/contacts/*.java" />
              <include name="emailMarketing/DomainKeys/*.java" />
              <include name="emailMarketing/lists/*.java" />
              <include name="emailMarketing/messages/*.java" />
              <include name="emailMarketing/Segments/*.java" />
              <include name="emailMarketing/UploadContact/*.java" />
              <exclude name="emailMarketing/lists/ListArchive.java"/>
              <exclude name="emailMarketing/messages/MessageCreation.java" />
           </fileset>
        </batchtest>
        <jvmarg value="-Duser=${user}"/>
        <jvmarg value="-Dpw=${pw}"/>
        <jvmarg value="-Dbrowser=${browser}"/>
        <jvmarg value="-Dserver=${server}"/>
        <jvmarg value="-Dopen=${open}"/>
        <jvmarg value="-DtestType=regression"/>
    </junit>
    <junitreport todir="${target.reports.dir}">
        <fileset dir="${target.reports.dir}">
            <include name="TEST-*.xml"/>
        </fileset>
        <report todir="${target.reports.dir}"/>
    </junitreport>
    <fail if="junit.failure" message="Test(s) failed.  See reports!"/>
    <fail if="junit.error" message="Test(s) errored.  See reports!"/>
</target>

【问题讨论】:

  • 但是为什么呢?如果它第一次失败,我希望它在所有后续运行中都会失败。如果它的输出随机变化,您可能需要进行更具确定性的测试。
  • 您可以按照*.com/questions/8295100/…中的描述创建规则
  • @RobHruska 我只想重新运行失败,因为我的日志有调试消息,如果 (1) 它更小 (2) 只包含相关信息会更好。

标签: ant junit hudson


【解决方案1】:

JUnit 1.8.0 有一个用于 junit 的“失败”格式化程序,可用于创建仅包含失败测试的 TestCase。见http://ant.apache.org/manual/Tasks/junit.html

The fourth formatter named failure (since Ant 1.8.0) collects all failing testXXX()
methods and creates a new TestCase which delegates only these failing methods.
The name and the location can be specified via Java System property or Ant property
ant.junit.failureCollector. The value has to point to the directory and the name of
the resulting class (without suffix). It defaults to java-tmp-dir/FailedTests.

【讨论】:

【解决方案2】:
【解决方案3】:

看看 Ant Retry 任务。

<target name="myTest1">
    <mkdir dir="${junit.output.dir}" />
    <retry retrycount="3">
      <junit haltonerror="yes" haltonfailure="yes" 
             fork="no" printsummary="withOutAndErr" 
             showoutput="true" tempdir="c:/tmp">
      <formatter type="xml" />
      <test name="MyPackage.myTest1" todir="${junit.output.dir}" />
      <classpath refid="Libs.classpath" />
      <formatter type="brief" usefile="false"/>
      </junit>
    </retry>
</target>

【讨论】:

    【解决方案4】:

    测试应该是确定性的,这样错误是可重现的。因此,立即重新运行失败的测试将再次失败。

    测试应该是独立的,即每个测试都应该进行自己的设置(和拆卸)。使用 junit,您通常没有执行测试的特定顺序。因此没有必要重新运行 test6 来设置 test7 的环境。

    如果您想要测试用例优先级,即在代码修复后重新运行测试时从失败的测试开始:

    【讨论】:

    • 仅仅因为它们是确定性的并不意味着如果只有一个测试失败,您就应该重新运行 1000 个测试。至于独立性,只有单元测试应该是独立的,功能测试有依赖关系其实很有用。
    • 立即重新运行(即不更改任何代码)任何数量的测试没有意义;)但是感谢您的评论 - 我倾向于在阅读“junit”时戴上单元测试的帽子。 ...并非所有测试框架都可以涵盖整个功能测试以及您的 TestNG ;)
    • 我寻找这个的原因是因为目前我们的测试套件正在使用 Sikuli 运行超过 300 次 UI 测试。所有测试都可以自行运行,但有时它们会因随机原因而失败。例如,在登录 Web 应用程序后加载速度不够快(60 秒)并且它超时并给出错误的失败。测试失败不是因为正在测试的原因,而是由于 Web 应用程序、互联网和 Hudson Box 的性能不佳。这就是为什么我想知道是否有可能尝试删除只是应用程序加载缓慢的虚假 UI 故障。感谢您的快速回复。
    • IC。对于单元测试,我会考虑使用测试替身。但这听起来好像您正在使用 junit 进行系统测试。对吗?
    • JohnMiller:瞬态故障是一个大问题,您应该尽最大努力消除它。一旦你开始认为某些失败是可以的,他们最终会掩盖一个重要的失败。暂时失败的测试不会向您的测试报告添加任何内容,因此您应该修复它们或删除它们,直到您可以编写更好的测试。
    最近更新 更多