我们首先将我们的ant构建封装在maven中,开始向maven迁移。
我们可以让maven来构建项目,但不能运行测试。我们正在尝试从maven执行build.xml中的ant测试目标。当然,当我们从ant运行测试目标时,一切都很好。
下面是一个测试类显示的错误(其他测试类相同)。这个类中有几个测试方法,但没有一个正在运行。这似乎是JUnit版本的问题;测试是JUnit4测试,如果我们更改测试类以扩展TestCase(JUnit3风格),它就会找到测试。
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)
这是我们的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>
这是我的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>
更新:
那么,当我们告诉maven使用JUnit4时,为什么它要使用JUnit3呢?我运行了mvn-X测试,发现JUnit 3.8.1 jar由于某种原因被拉入,但我不知道如何找出原因。
更新:
我发现maven antrun插件依赖于junit 3.8.1http://maven.apache.org/plugins/maven-antrun-plugin/dependencies.html
这就解释了Junit 3是如何被拉进来的
那我现在该怎么办?有没有一种方法可以使用maven-antrun插件通过build.xml中的ant任务来运行我的JUnit4测试?
这不是对这个问题的直接回答,而是我对处理这个问题的建议(因此我首先将其作为评论):
移动到maven不应该通过包装ant目标来完成。尽量(至少)采用maven标准目录布局。如果不能做到这一点,请尝试通过配置更改标准maven测试源目录(覆盖Supor POM设置)。最后使用maven构建生命周期进行编译和测试。
不确定您是否仍然需要解决这个问题,但我们也遇到了类似的问题。
您可以使用junit.framework.JUnit4TestAdapter
类在Junit 3测试运行器中运行Junit 4测试。
因此,以测试类为例,您可以简单地将以下方法定义添加到类中:
public static junit.framework.Test suite() {
return new junit.framework.JUnit4TestAdapter(ExampleBaseObjectDaoTest.class);
}
然后测试应该在maven中运行。
此解决方案的缺点是,您需要将suite()
方法添加到所有测试类中。
以防有人仍在为此而挣扎。。。
我有同样的";没有发现测试";问题,并尝试添加扩展TestCase和添加suite()方法。这种方法有效(取决于使用的TestRunner),但不是很令人满意。
我偶然发现了一个更好的运行Ant JUnit4测试任务的解决方案:
- 在maven-antrun插件配置中包括以下依赖项:
<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>
请注意,我使用的是依赖于1.9.4版本的antrun-maven插件3.0.0版本。此解决方案也适用于1.9.15版本的依赖项。1.10.x依赖项不起作用,但我没有很努力。
- 为Ant junit目标创建一个执行,如下所示:
<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>
注意,我已经将maven_test_classpath和maven_plugin_classpath传递给Ant,因为我希望maven管理依赖关系并生成适当的类路径。
- 在build.xml文件任务配置中,包括引用从Maven传入的类路径的子元素:
<junit... >
...
<classpath>
<pathelement path="${maven_test_classpath}" />
<pathelement path="${maven_plugin_classpath}" />
</classpath>
...
</junit>
注意,我发现maven_plugin_classpath实际上并不是必需的。我保留了它的配置,因为我不明白为什么不需要它。YMMV。
结果是使用junit、batchtest和junistport元素在Ant中运行各种复杂的JUnit4单元和集成测试。不需要扩展TestCase和添加静态suite()方法。