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 &lt;path id="test.classpath"/&gt; 定义它们,并使用类似 &lt;classpath refid="test.classpath" /&gt; 的 Junit 声明将它们添加到您的类路径中。 我已经在 中引用了如上所示的内容,而 CLASSPATH_JUNIT 正在引用上面显示的记录器和其他 jar 文件以及更新的内容。 好的,知道了。但是,JUnit 似乎没有找到它。你能打印你的路径并检查它是否真的存在吗?我认为您可以这样做:&lt;echo message="$toString:CLASSPATH_JUNIT"/&gt;。或者,尝试将完整的 JAR 路径和文件名分配给 &lt;pathelement location=".."/&gt;,看看是否可行。 打印为 C:\build_libs\ESW\log4j-1.2.15.jar;并且该位置存在相同的罐子。假设如果它不可用,当我给 fork=no 那么它是如何工作的?

以上是关于junit 测试和非 junit 测试与 ant 目标的主要内容,如果未能解决你的问题,请参考以下文章

从 ant 执行的 junit 测试未加载 DLL

如何让 JUnit 测试(从 Ant 脚本驱动)转储导致失败的异常堆栈?

如何将 JUnit Ant 任务配置为仅在失败时生成输出?

搭建持续集成单元测试平台(Jenkins+Ant+Java+Junit+SVN)

Junit ant 任务未将断言错误报告为失败

jenkins+ant+junit怎样输出报告