2

We are starting the move to maven by first wrapping our ant builds in maven.

We can get maven to build the project, but not to run the tests. We are trying to execute the ant test target, in build.xml, from maven. Of course when we run the test target from ant everything is fine.

Below is the error that is displayed for one test class (same for others). This class has several test methods in it, but none are getting run. This seems to be a JUnit version problem; the tests are JUnit 4 tests, and if we change the test class to extend TestCase (JUnit 3 style) it finds the tests.

No tests found in org.mathforum.common.dao.ExampleBaseObjectDaoTest

junit.framework.AssertionFailedError: No tests found in org.mathforum.common.dao.ExampleBaseObjectDaoTest   at 
org.apache.maven.plugin.antrun.AntRunMojo.execute(AntRunMojo.java:327)  at 
org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490) at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694) at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556) at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535)  at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387) at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)  at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)  at 
org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)  at 
org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)    at 
org.apache.maven.cli.MavenCli.main(MavenCli.java:362)   at 
org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60) at 
org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315) at 
org.codehaus.classworlds.Launcher.launch(Launcher.java:255) at     
org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)   at     
org.codehaus.classworlds.Launcher.main(Launcher.java:375)

Here's our pom:

<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>mf-common</artifactId>
<groupId>org.mathforum</groupId>
<version>1.0-SNAPSHOT</version>
<build>
    <plugins>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <dependencies>
                <dependency>
                    <groupId>com.sun</groupId>
                    <artifactId>tools</artifactId>
                    <version>1.5.0</version>
                    <scope>system</scope>
                    <systemPath>${java.home}/../lib/tools.jar</systemPath>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId> <!-- apectj ant plugin -->
                    <version>1.6.1</version>
                </dependency>
                <dependency>
                    <groupId>ant</groupId>
                    <artifactId>ant-junit</artifactId>
                    <version>1.6.5</version>
                    <!--scope>test</scope -->
                </dependency>
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.8.2</version>
                    <!--scope>test</scope -->
                </dependency>
                <dependency>
                    <groupId>commons-net</groupId>
                    <artifactId>commons-net</artifactId>
                    <version>1.4.1</version>
                </dependency>
            </dependencies>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <configuration>
                        <target>
                            <ant antfile="${basedir}/build.xml">
                                <target name="build" />
                            </ant>
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test</id>
                    <phase>test</phase>
                    <configuration>
                        <target>
                            <ant antfile="${basedir}/build.xml">
                                <target name="test" />
                                <!-- need test failure to fail the build -->
                            </ant>
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
<dependencies>
    <dependency>
        <groupId>ant</groupId>
        <artifactId>ant-junit</artifactId>
        <version>1.6.5</version>
        <!--scope>test</scope -->
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.2</version>
        <!--scope>test</scope -->
    </dependency>
</dependencies>
</project>

And here is my build.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<project basedir="." default="build" name="mf-common" xmlns:aspectj="antlib:org.aspectj">
<path id="EAR Libraries.libraryclasspath" />
<path id="aspectj.libraryclasspath">
    <fileset dir="lib">
        <include name="*.jar" />
    </fileset>
</path>
<path id="common.classpath">
    <fileset dir="test/lib">
        <include name="*.jar" />
    </fileset>
    <path refid="aspectj.libraryclasspath" />

    <path refid="EAR Libraries.libraryclasspath" />
</path>

<taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
    <classpath>
        <path refid="common.classpath" />
        <pathelement location="lib/aspectjtools.jar" />
    </classpath>
</taskdef>

<property environment="env" />
<property name="debuglevel" value="source,lines,vars" />
<property name="target" value="1.6" />
<property name="source" value="1.6" />

<target name="init">
    <mkdir dir="bin" />
    <copy includeemptydirs="false" todir="bin">
        <fileset dir="src" excludes="**/*.launch, **/*.java" />
    </copy>
    <copy includeemptydirs="false" todir="bin">
        <fileset dir="test/src" excludes="**/*.launch, **/*.java" />
    </copy>
</target>

<target name="clean">
    <delete dir="bin" />
    <delete file="dist/${ant.project.name}.jar" />
</target>

<target depends="clean" name="cleanall" />

<target depends="init" name="build">
    <echo message="${ant.project.name}: ${ant.file}" />

    <javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
        <src path="src" />
        <classpath refid="common.classpath" />
    </javac>
    <javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
        <src path="test/src" />
        <classpath refid="common.classpath" />
    </javac>
    <copy includeemptydirs="false" todir="bin">
        <fileset dir="src" excludes="**/*.launch, **/*.java" />
    </copy>
    <copy includeemptydirs="false" todir="bin">
        <fileset dir="test/src" excludes="**/*.launch, **/*.java" />
    </copy>

    <echo message="after javac" />

    <aspectj:iajc debug="true" noweave="true" outJar="dist/mf-common.jar" sourceRootCopyFilter="**/CVS/*,**/*.java,**/*properties" sourceroots="bin/" source="${source}" target="${target}">
        <classpath refid="common.classpath" />
    </aspectj:iajc>

</target>

<target name="test" depends="build">
    <ant dir="${basedir}" inheritAll="false" antfile="test.xml" />
</target>
</project>

UPDATE:

So why is maven running with JUnit 3 when we told it to use JUnit 4? I ran mvn -X test and saw that the JUnit 3.8.1 jar is being pulled in for some reason, but I don't know how to figure out why.

UPDATE:

I found that the maven antrun plugin depends on junit 3.8.1 http://maven.apache.org/plugins/maven-antrun-plugin/dependencies.html

So that explains how Junit 3 is getting pulled in.

So what do I do now? Is there a way to run my JUnit 4 tests via an ant task in build.xml using the maven antrun plugin?

atroutt
  • 471
  • 6
  • 14
  • Are you sure the Junit dependency in Maven is being used? Maybe it is the Junit library accessed by ANT that is being used. – ziggy Mar 07 '12 at 20:48
  • I looked in to it and the maven antrun plugin depends on junit 3.8.1, so that is why. – atroutt Mar 07 '12 at 21:13
  • I learned from this http://stackoverflow.com/questions/2021771/surefire-is-not-picking-up-junit-4-tests, which is similar, but there is no solution there except maybe to remove plugin that is causing the conflict. I can't remove antrun unless there is another way to run ant from maven. – atroutt Mar 07 '12 at 21:30
  • 1
    Moving to maven should not be done by wrapping ant targets. Try to (at least) adopt the [maven standard directory layout](http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html). If you can not do this, try to change the standard maven test source directoy by configuring [](http://maven.apache.org/pom.html#The_Super_POM) (overwrite the Supor POM setting). And finally use the maven [build lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) to compile and test. – FrVaBe Mar 08 '12 at 08:19
  • Hey @FrVaBe I'd like to accept your comment as the answer. Can you put that in an answer? – atroutt Aug 06 '12 at 13:18

3 Answers3

1

Not sure if you still need a solution to this problem, but we had a similar issue.

You can run your Junit 4 tests in Junit 3 test runners with the junit.framework.JUnit4TestAdapter class.

So using your test class as an example you can simply add the following method definition to the class:

public static junit.framework.Test suite() {
    return new junit.framework.JUnit4TestAdapter(ExampleBaseObjectDaoTest.class);
}

The test should then run in maven.

The downside to this solution is that you will need to add the suite() method to all of your test classes.

DB5
  • 13,553
  • 7
  • 66
  • 71
  • Thanks! I just gave up on trying to run the ant targets from maven, like @FrVaBe suggested in the comments above. – atroutt Aug 06 '12 at 13:16
1

This is not a direct answer to the question but my recommendation to handle the issue (thus I first put it as a comment):

Moving to maven should not be done by wrapping ant targets. Try to (at least) adopt the maven standard directory layout. If you can not do this, try to change the standard maven test source directoy by configuration (overwrite the Supor POM setting). And finally use the maven build lifecycle to compile and test.

FrVaBe
  • 47,963
  • 16
  • 124
  • 157
1

Just in case anyone is still struggling with this...

I had the same "no tests found" problem and tried adding extending TestCase and adding suite() method as above. This sort of worked (depending on the TestRunner used) but was not very pleasing.

I stumbled upon a better solution for running Ant JUnit4 test tasks:

  1. include the following dependencies in the maven-antrun-plugin configuration:
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
</dependency>
<dependency>
    <groupId>org.apache.ant</groupId
    <artifactId>ant</artifactId>
    <version>1.9.4</version>
</dependency>
<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant-junit</artifactId>
    <version>1.9.4</version>
</dependency>
<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant-junit4</artifactId>
    <version>1.9.4</version>
</dependency>

Note that I am using antrun-maven-plugin version 3.0.0 with version 1.9.4 dependencies. This solution also works with version 1.9.15 dependencies. Didn't work with 1.10.x dependencies, but I didn't try very hard.

  1. Create an execution for the Ant junit target something like:
<execution>
    <id>ant-unit-tests</id>
    <phase>whatever</phase>
    <goals><goal>run</goal></goals>
    <configuration>
        <target>
            <property name="maven_test_classpath" refid="maven.test.classpath"/>
            <property name="maven_plugin_classpath" refid="maven.plugin.classpath"/>
            <ant antfile="${project.basedir}/your_build.xml" target="your_ant_target" />
        </target>
    </configuration>
</execution>

Note that I have passed maven_test_classpath and maven_plugin_classpath to Ant, because I want Maven to manage dependencies and produce appropriate classpaths.

  1. In build.xml file task configuration, include child elements that refers to the classpaths you passed in from Maven:
<junit... >
    ...
    <classpath>
        <pathelement path="${maven_test_classpath}" />
        <pathelement path="${maven_plugin_classpath}" />
    </classpath>
    ...
</junit>

Note that I discovered maven_plugin_classpath was not actually required. I kept its configuration because I don't understand WHY it is not required. YMMV.

The result runs all sorts of complicated JUnit4 unit and integration tests executed in Ant using junit, batchtest, and junitreport elements. Extending TestCase and adding static suite() method are not needed.

David Brossard
  • 13,584
  • 6
  • 55
  • 88
someguy
  • 11
  • 1
  • Excellent, thanks, worked for me. I need to run junit4 under ant under maven just to have all our tests in one place. Took a lot of googling to find your answer! For me it worked without the junit dependency and without the `maven_test_classpath` element. – Dave Griffiths Dec 01 '20 at 09:44