0

I would like to set things up via Ant to run my JUnit tests and report on things both at a summary level and an individual class level. I'd like to have all of the tests run, even if there are some errors, but have the overall build fail if there are any errors.

Here's what I currently have in the build.xml file:

  <target name = "test" depends="compiletest" description="run unit tests">
    <junit haltonfailure="yes">
      <classpath path="${buildtest}">
        <path refid="test.classpath"/>
      </classpath>
      <batchtest fork="yes">
        <formatter type="brief" usefile="false"/>
        <fileset dir="${test}">
          <include name="**/*Test.java"/>
          <include name="**/Test*.java"/>
        </fileset>
      </batchtest>
    </junit>
  </target>

Assuming I have two test classes, each of which has 1 error in it, it would produce the following output:

Buildfile: /opt/project/build/build.xml

init:

compile:

compiletest:

test:
    [junit] Testsuite: com.company.foo.TestQuoteParser
    [junit] Tests run: 3, Failures: 1, Errors: 0, Time elapsed: 0.013 sec
    [junit]
    [junit] Testcase: thisShouldThrowException(com.company.foo.TestQuoteParser):    FAILED
    [junit] Expected exception: java.lang.RuntimeException
    [junit] junit.framework.AssertionFailedError: Expected exception: java.lang.RuntimeException
    [junit]
    [junit]

BUILD FAILED
/opt/project/build/build.xml:88: Test com.company.foo.TestQuoteParser failed

Total time: 1 second

What I'd like is for each test class to get executed, whether or not previous test classes passed or failed, yet still have the overall build fail. It seems like I can either have the build fail on the first failure/error or have all tests run but the build succeeds. I'd also like to get an overall summary printed at the end. Something like this:

Buildfile: /opt/project/build/build.xml

init:

compile:

compiletest:

test:
    [junit] Testsuite: com.company.foo.TestQuoteParser
    [junit] Tests run: 3, Failures: 1, Errors: 0, Time elapsed: 0.013 sec
    [junit]
    [junit] Testcase: thisShouldThrowException(com.company.foo.TestQuoteParser):    FAILED
    [junit] Expected exception: java.lang.RuntimeException
    [junit] junit.framework.AssertionFailedError: Expected exception: java.lang.RuntimeException
    [junit]
    [junit]

    [junit] Testsuite: com.company.foo.TestEntityParser
    [junit] Tests run: 6, Failures: 1, Errors: 0, Time elapsed: 0.023 sec
    [junit]
    [junit] Testcase: thisShouldThrowException(com.company.foo.TestEntityParser):   FAILED
    [junit] Expected exception: java.lang.RuntimeException
    [junit] junit.framework.AssertionFailedError: Expected exception: java.lang.RuntimeException
    [junit]
    [junit] 
    [junit] Summary: com.company
    [junit] Tests run: 9, Failures: 2, Errors: 0, Time elapsed: 0.038 sec

BUILD FAILED
/opt/project/build/build.xml:88: 2 failures 
Total time: 1 second

I'd rather get all of this to the screen and not have to go looking at files (even pretty HTML report files), since work will be done via SSH. Is any of that that easily doable?

Joe Casadonte
  • 15,888
  • 11
  • 45
  • 57
  • have you considered using Jenkins to build your project. I know Jenkins would run all your test cases even though some of em are error prone – Ashish Dec 26 '13 at 23:48
  • 1
    [Here is (link)](http://stackoverflow.com/questions/4038547/how-can-i-have-the-ant-junit-task-run-all-tests-and-then-stop-the-rest-of-the-bu) how you can continue executing tests but fail the build at the end. – srkavin Dec 27 '13 at 00:42

1 Answers1

0

When you setup JUnit, set both haltonerror and haltonfailure to false. This way, JUnit will continue processing. Then, also setup errorproperty and failureproperty parameters too. Run JUnit as you normally would. If you want to produce the report, produce the report. Then use the <fail/> task to fail the build if either the error property or failure property report an error:

<target name = "test"
    depends="compiletest"
    description="run unit tests">
    <junit haltonfailure="false"
        haltonerror="false"
        failureproperty="failure.in.testing"
        errorproperty="error.in.testing">
        <classpath path="${buildtest}">
            <path refid="test.classpath"/>
        </classpath>
        <batchtest fork="yes">
            <formatter type="brief" usefile="false"/>
            <fileset dir="${test}">
                <include name="**/*Test.java"/>
                <include name="**/Test*.java"/>
            </fileset>
        </batchtest>
    </junit>

    <!-- Now that everything has run, we'll check the error.in.testing -->
    <!-- and the failure.in.testing properties to see if there were errors -->
    <!-- of failed tests. -->
    <fail message="JUnit had at least one error in a test${line.break}${error.in.testing}">
        <condition>
            <length string="${error.in.testing}"
                when="greater" length="0"/>
        </condition>
    </fail>
    <fail message="JUnit had at least one failed test${line.break}${failure.in.testing}">
        <condition>
            <length string="${failure.in.testing}"
                when="greater" length="0"/>
        </condition>
    </fail>
</target>

I MAY have been able to use the isset condition:

    <fail message="JUnit had at least one error in a test${line.break}${error.in.testing}">
        <condition>
            <isset property"error.in.testing"/>
        </condition>
    </fail>
    <fail message="JUnit had at least one failed test${line.break}${failure.in.testing}">
        <condition>
            <isset property"failure.in.testing"/>
        </condition>
    </fail>

However, I wasn't sure whether these properties are unset or merely equal to a null string.

David W.
  • 105,218
  • 39
  • 216
  • 337