junit 测试和非 junit 测试与 ant 目标
Posted
技术标签:
【中文标题】junit 测试和非 junit 测试与 ant 目标【英文标题】:junit test and non junit test with ant target 【发布时间】:2011-06-16 07:51:33 【问题描述】:<junit printsummary="on" fork="yes" forkmode="once"
haltonerror="false" haltonfailure="false"
failureproperty="junit.failure" showoutput="false" maxmemory="1024m">
<classpath>
<path refid="CLASSPATH_JUNIT"/>
<dirset dir="$TEST_BUILD_DIR"/>
</classpath>
<batchtest fork="no" todir="$TEST_BUILD_DIR">
<fileset dir="$COMP_TEST_SRC">
<include name="**/*Test.java" />
<include name="**/Test*.java" />
<exclude name="**/EswTestCase.java" />
</fileset>
</batchtest>
<formatter type="xml" />
</junit>
生成 xml 报告需要花费大量时间,并且会出现以下错误:
Caught an exception while logging the end of the build. Exception was:
java.lang.OutOfMemoryError: PermGen space
为什么生成 xml 需要很长时间?如何解决此错误并使应用程序快速运行。我最多只有 10 个测试文件。我使用命令提示符来执行 ant 脚本。
分析:
1) 如果我只为扩展 Junit 测试的测试类运行批处理测试,它执行得非常快。例如:
公共类 ImpactsParserTest 扩展 测试用例..
2)现在,如果我有一个扩展 spring junit 测试的测试类:
公共类 AddressLookupServiceTest 扩展 EswTestCase..
公共类 EswTestCase 扩展 AbstractDependencyInjectionSpringContextTests..
这会导致 junit 目标运行非常缓慢并导致内存不足错误。为什么会这样?
3) 当我使用 batchtest fork="yes" 而不是 no 时,构建速度很快并且不会导致内存不足。但是,它会引发如下错误:
java.lang.NoClassDefFoundError
at org.apache.log4j.Logger.getLogger(Logger.java:118)
..
java.lang.NoClassDefFoundError: com.bgc.ordering.wizard.back.services.EswTestCase
尽管如此,我在类路径元素中将这些 jar 文件和类文件指定为:
和记录器 jar
<path id="CLASSPATH_JUNIT">
<fileset dir="$BUILD_LIBS_HOME">
<include name="*.jar" />
</fileset>
<pathelement location="$TEST_CLASSES_DIR" />
<pathelement location="$TEST_BUILD_DIR" />
<pathelement location="$COMP_BUILD" />
<pathelement location="$COMP_CLASSES" />
<path location="$APP_DIR\bgc-esw-services\target\classes"/>
<pathelement location="$APP_DIR\bgc-esw-web\target\classes" />
...
log4j.properties 存在于$TEST_BUILD_DIR
使用:apache-ant-1.8.1 和 junit-3.8.1.jar
【问题讨论】:
【参考方案1】:当 JVM 用完永久代堆中的空间时,会发生此错误。虚拟机中的内存被划分为多个区域。这些地区之一是 PermGen。它是用于(除其他外)加载类文件的内存区域。此内存区域的大小是固定的,即它在 VM 运行时不会改变。您可以使用命令行开关指定此区域的大小:-XX:MaxPermSize
。 Sun VM 上的默认值为 64 Mb。要解决这个问题,你可以给它一个更高的值,比如 256mb。
我的猜测是,您不仅要运行单元测试,还要运行集成测试,例如你有一个用 Spring 连接的类,你需要它们的依赖项。这就是为什么你有EswTestCase
。如果您只想编写单元测试,我建议您实例化您的类并将依赖项模拟到您未直接测试的其他类。这将最大限度地减少您的内存占用,因为您不必创建 Spring 应用程序上下文。
这就是JavaDoc 所说的AbstractDependencyInjectionSpringContextTests
:
真正用于集成测试,而不是 单元测试。你通常不应该 使用 Spring 容器作为单元 测试:只需将您的 POJO 填充到 普通的 JUnit 测试!
从 Spring 3.0 开始,旧的 JUnit 3.8 基类层次结构(即 AbstractDependencyInjectionSpringContextTests、AbstractTransactionalDataSourceSpringContextTests 等)已正式弃用,并将在以后的版本中删除。建议您使用Spring TestContext Framework 编写集成测试。您应该使用注释,而不是使用 AbstractDependencyInjectionSpringContextTests
扩展 EswTestCase
。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class EswTestCase
...
【讨论】:
(我已经更新了上面的主要问题。)这是很好的信息,但是如果我使用EswTestCase
派生的所有测试用例都失败了。不必创建 Spring 应用程序上下文肯定会更快并且消耗更少的内存。你的测试报告应该显示他们失败了。看起来您的应用程序库在类路径中不可用,即使您声明了它们。我建议您使用 Ant <path id="test.classpath"/>
定义它们,并使用类似 <classpath refid="test.classpath" />
的 Junit 声明将它们添加到您的类路径中。
我已经在 <echo message="$toString:CLASSPATH_JUNIT"/>
。或者,尝试将完整的 JAR 路径和文件名分配给 <pathelement location=".."/>
,看看是否可行。
打印为 C:\build_libs\ESW\log4j-1.2.15.jar;并且该位置存在相同的罐子。假设如果它不可用,当我给 fork=no 那么它是如何工作的?以上是关于junit 测试和非 junit 测试与 ant 目标的主要内容,如果未能解决你的问题,请参考以下文章
如何让 JUnit 测试(从 Ant 脚本驱动)转储导致失败的异常堆栈?