Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run all JUnit tests in a category/suite with Ant?

I'm using JUnit Categories and ClassPathSuite in a setup similar to that described in this answer. To recap:

public interface FastTests {
}

@RunWith(Categories.class)
@Categories.IncludeCategory(FastTests.class)
@Suite.SuiteClasses(AllTests.class)
public class FastTestSuite {
}

@RunWith(ClasspathSuite.class) 
public class AllTests {
}

...where AllTests makes use of the ClasspathSuite library.

A test class that's part of the FastTests category would look like this:

@Category(FastTests.class)
public class StringUtilsTest {
    //  ...
}

When I run "FastTestSuite" in my IDE, all tests with the FastTests annotation are executed, nice & smooth:

enter image description here

Now, I want to do the same thing with Ant. (To my surprise, I couldn't easily find instructions for this on SO.) In other words, I need an Ant target that runs all tests with the FastTests annotation.

I've tried some simplistic approaches using <test> or <batchtest>...

 <junit showoutput="true" printsummary="yes">
     <test name="fi.foobar.FastTestSuite"/>
     <formatter type="xml"/>
     <classpath refid="test.classpath"/>
 </junit>

... but no luck, so far.

Edit: Besides the IDE, it works fine with JUnitCore on the command line:

$ java -classpath "classes:WebContent/WEB-INF/lib/*" org.junit.runner.JUnitCore fi.foobar.FastTestSuite
.............
Time: 0.189

OK (13 tests)
like image 535
Jonik Avatar asked Jun 03 '11 10:06

Jonik


2 Answers

Right, I got it working with <batchtest> quite simply:

<junit showoutput="true" printsummary="yes" fork="yes">
    <formatter type="xml"/>
    <classpath refid="test.classpath"/>
    <batchtest todir="${test.reports}">
        <fileset dir="${classes}">
            <include name="**/FastTestSuite.class"/>
        </fileset>
    </batchtest>
</junit>

I had tried <batchtest> earlier, but had made the silly mistake of using "**/FastTestSuite.java" instead of "**/FastTestSuite.class" in the <include> element... Sorry about that :-)

NB: it's necessary to set fork="yes" (i.e., run the tests in a separate VM); otherwise this will also produce "initializationError" at java.lang.reflect.Constructor.newInstance(Constructor.java:513) like <test> (see comments on the question). However, I couldn't get <test> working even with fork="yes".

The only shortcoming is that this produces just one JUnit XML report file (TEST-fi.foobar.FastTestSuite.xml) which makes it look like all the (hundreds) of tests are in one class (FastTestSuite). If anyone knows how to tweak this to show the tests in their original classes & packages, please let me know.

like image 113
Jonik Avatar answered Oct 05 '22 04:10

Jonik


I found a workaround to use ant's junit task to run test of a specific Category:

<target name="test" description="Run Selenium tests by category">
    <fail unless="category.name" message="Please specify 'category.name' property"/>

    <junit showoutput="true" printsummary="true" fork="true">
        <formatter type="xml"/>
        <classpath refid="test.classpath"/>

        <batchtest todir="${test.reports}" haltonfailure="false">
            <fileset dir="${classes}">
                <!-- regex '^\s*@Category' part added to ensure @Category annotation is not commented out -->
                <containsregexp expression="^\s*@Category.*${category.name}"/>
            </fileset>
        </batchtest>
    </junit>
</target>

Execute test by supplying category.name property to ant like this:

ant -Dcategory.name=FastTests test

Using batchtest will also produce separate JUnit XML report files per test (e.g. TEST-fi.foobar.FastTestClassN.xml).

like image 27
R. Oosterholt Avatar answered Oct 05 '22 06:10

R. Oosterholt