24

We have migrated to both JUnit 4 and ant 1.7

The tests runs fine in eclipse, but the annotations are ignored when running the tests using ant.

According to the Ant junit task documentation:

It also works with JUnit 4.0, including "pure" JUnit 4 tests using only annotations and no JUnit4TestAdapter.

But the documentation doesn't elaborate on how it should be configured.

Is there any special setting required for the junit task? Am I missing something? We have both Tests that extends TestCase (i.e. 3.8 style) and "pure" Junit 4 tests, could that be the problem?

martin clayton
  • 76,436
  • 32
  • 213
  • 198
LiorH
  • 18,524
  • 17
  • 70
  • 98

9 Answers9

15

I am using pure JUnit4 tests with Ant.

Here is the interesting part of my build file:

<junit printsummary="yes" haltonfailure="yes">
    <formatter type="xml"/>
    <classpath refid="path.test"/>
    <batchtest fork="yes" todir="${dir.report.unittests.xml}">
        <fileset dir="src">
            <include name="**/*Test*.java"/>
        </fileset>
    </batchtest>
</junit>

Make sure you have the latest version of the junit.jar file in the lib directory of Ant. As far as I know the required version is delivered with ant 1.7 or higher versions...

informatik01
  • 16,038
  • 10
  • 74
  • 104
Homes2001
  • 1,059
  • 8
  • 14
  • 3
    So there's no way to avoid having to use a naming pattern for test classes (like "*Test.java") even though JUnit 4 doesn't require that? – Jonik Oct 04 '10 at 12:22
  • @jonik You don't have to use a naming pattern but it will help you avoid running JUnit against any additional classes you might have which don't contain tests that are in the same package as your test classes. Classes like this will give errors in the JUnit output. – MikeD Mar 22 '12 at 15:53
  • 3
    What if you have utility classes which happen to have Test at the start but which aren't test classes? Usually, "using JUnit 4" means "the @Test annotation marks tests, not the class name". It should be possible to include all .java files and have it only run the ones with tests in them. – Hakanai Nov 08 '12 at 00:04
  • 3
    @Trejkaz There is a new parameter added that will filter out non-test classes for you. It is in an [answer below.](http://stackoverflow.com/questions/635481/running-pure-junit-4-tests-using-ant/25148876#25148876) – Bryce Aug 08 '14 at 18:19
7

Ant ships with a version of JUnit 3 by default. JUnit 3 has no support for test annotations.

To use the JUnit 4 annotations from the junit task make sure that you provide the location of a JUnit 4 jar in a nested classpath element of the junit task (see this entry in the ant FAQ).

<junit showoutput="yes" fork="true">
    <classpath>
        <!-- The location of the JUnit version that you want to use -->
        <pathelement location="lib/junit-4.9b1.jar"/>
    </classpath>

    <formatter type="plain" usefile="false" />

    <batchtest>
        <fileset dir="${tests.dir}"/>
    </batchtest>
</junit>

This is a preferable solution to overwriting the ant-junit.jar in ANT_HOME/lib as it means you can keep your JUnit jar in source control alongside your code making upgrades to later versions straightforward.

Note that whilst I haven't specified any include pattern in my fileset above this does mean that the junit task will attempt to run JUnit against all the classes in that directory structure which might result in a number of classes being included that don't contain any tests depending on how you have structured your source files.

MikeD
  • 5,004
  • 1
  • 25
  • 39
  • I have exactly the same problem in Debian: ant 1.8.0, junit 4.10, the classpath to the junit-4.10.jar added as part of the junit task and yet, the annotation @Task is not recognized, only renaming the methods to start with test* works ... – Marcus Junius Brutus Apr 20 '12 at 11:54
  • @MenelaosPerdikeas Did you mean `@Task`? I would expect you to be using `@Test` as the annotation. Assuming you are using `@Test` try running ant with the -v flag and the output of the junit task will show a classpath. You can then ensure that the junit-4.10.jar classpath that you added to the task is present. I found -v really helpful when trying to diagnose this problem. – MikeD Apr 20 '12 at 12:59
  • I had exactly this `` element except for the `fork="true"` option. Adding that option solved it for me. – Darkhogg Oct 23 '13 at 21:44
3

You can finally only find and execute tests with the skipNonTests parameter added in ant 1.9.3+!

This is the code snippet from the accepted answer above (except for the new skipNonTests parameter and getting rid of the "Test" in the filename requirement):

<junit printsummary="yes" haltonfailure="yes">
    <formatter type="xml"/>
    <classpath refid="path.test"/>
    <batchtest skipNonTests="true" fork="yes" todir="${dir.report.unittests.xml}">
        <fileset dir="src">
            <include name="**/*.java"/>
        </fileset>
    </batchtest>
</junit>
11101101b
  • 7,679
  • 2
  • 42
  • 52
  • Yeah, it's great that they finally added this. Now if they could just fix everything-else-in-Ant, Ant might actually become a nice tool. Haha. – Hakanai Aug 12 '14 at 05:47
2

This happened to me and it was because I was both using annotations and extending TestCase.

public class TestXXX extends TestCase {

    @Test
    public void testSimpleValidCase() {
        // this was running
    }

    @Test
    public void simpleValidCase() {
        // this wasn't running
    }
}

When you extend TestCase you are assuming JUnit3 style so JUnit4 annotations are ignored.

The solution is to stop extending TestCase.

alves
  • 1,343
  • 1
  • 10
  • 16
1

Verify your classpath definition... this solved my problem.

<path id="classpath" description="Classpath do Projeto">
    <fileset dir="${LIB}">
        <include name="**/*.jar" />
        <exclude name="**/.SVN/*.*"/>
    </fileset>
</path>
0

I also tried to do tests with JUnit 4.0 without JUnit4TestAdapter, i.e. without method
public static junit.framework.Test suite() { return new JUnit4TestAdapter(SomeTestClass.class); }

I use ant 1.9.4. Running ant test verbose (ant -v ) shows

[junit] Running multiple tests in the same VM
[junit] Implicitly adding /usr/share/java/junit.jar:/usr/sharejava/ant-launcher.jar:/usr/share/java/ant.jar:/usr/share/java/ant/ant-junit.jar to CLASSPATH

Aha, but still there is some ant-junit-task. Downloading this shows in addition /usr/share/java/ant/ant-junit4.jar which is not added implicitly. I just added it explicitly:

<junit printsummary="yes" 
    fork="yes" 
    forkmode="once"
    maxmemory="1023m" 
    showoutput="no">
    ...
   <classpath>
     <pathelement path="...:${junitJar}:${hamcrestJar}:/usr/share/java/ant/ant-junit4.jar" />
   </classpath>
...
</junit>

and it worked. Without: no. I am aware that this solution is not beautiful at all...

user2609605
  • 419
  • 2
  • 14
0

Apply this annotation to the other classes org.junit.Ignore

Dennis C
  • 24,511
  • 12
  • 71
  • 99
0

This is the relevant part of my generic ant script... not sure if that'll help you or not..

 <junit fork="true"
        forkmode="once"
        haltonfailure="false"
        haltonerror="false"
        failureproperty="tests.failures"
        errorproperty="tests.errors"
        includeantruntime="true"
        showoutput="true"
        printsummary="true">
     <classpath>
         <path refid="path-id.test.classpath.run"/>
     </classpath>

     <formatter type="xml"/>

     <batchtest fork="yes"
                todir="${dir.build.testresults}">
         <fileset dir="${dir.src.tests}">
             <include name="**/*Test.java"/>
         </fileset>
     </batchtest>
 </junit>
TofuBeer
  • 60,850
  • 18
  • 118
  • 163
-1

What I ended up doing was adding an Ant to one of my definitions that is used by the task>. Et voila.