【问题标题】:How can I make Cobertura/Emma play nice with an Eclipse application?如何使 Cobertura/Emma 与 Eclipse 应用程序配合得很好?
【发布时间】:2010-10-13 22:45:01
【问题描述】:

我的公司正在升级我们的构建系统以使用 Buckminster(进展顺利)。如果我们能够在我们处理代码时自动生成他们用于代码的一些指标,经理们自然会喜欢它——其中一个指标是单元测试的覆盖率。

之前的构建是基于 PDE 的,它生成了一个单独的无头应用程序,该应用程序解析上下文中的所有插件,在其中查找测试类,将所有测试用例放入一个更大的套件中,然后以编程方式运行它,通过JUnitResultFormatter.startTestSuite()。在此过程中,它为特定元数据(版权标记等)添加了一些本地测试,并测试了包依赖性。

似乎我应该能够为测试应用程序导出产品,使用我选择的覆盖工具对其进行检测,然后运行它;但是,看起来两个覆盖工具都想知道他们正在处理的整个类路径。是否有可能使这些工具中的任何一个都运行良好,而无需在我的整个构建工作区中查找 jar 和依赖项?

【问题讨论】:

    标签: java eclipse cobertura headless emma


    【解决方案1】:

    在一个较旧的 SO 问题的帮助下,设法让一切正常工作。

    我们从 this post 开始,它为我们提供了使用 EMMA 的示例覆盖设置。然而,我们似乎需要在我们想要获取覆盖数据的每个插件上强制依赖 EMMA。

    一些 Google 取证让我们找到了this book excerpt,它相当充分地涵盖了 OSGi 类加载器层次结构。通过将osgi.parentClassloader=app 行添加到测试运行应用程序的config.ini,我们可以在命令行上指定一个类路径。该类路径需要包含:

    • Eclipse 的startup.jar
    • 应用程序使用的 Java SDK jars
    • 覆盖工具的 jars

    当然,我们是通过<java jar="foo.jar"> Ant 任务运行测试的,它会默默地忽略您提供的任何类路径信息并仅使用 jar。在我们让 Emma 工作后,我们切换到 Cobertura,我们最终的 Ant 脚本(略微删节和匿名化)看起来像:

    <target name="generate.coverage" depends="buckminster.init">
      <!-- Generate the classpath. -->
      <path id="cobertura.classpath">
        <fileset dir="${tasks.dir}/lib/cobertura">
          <include name="cobertura.jar" />
          <include name="**/*.jar" />
        </fileset>
      </path>
      <taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
    
      <!-- Get ready to run the unit tests app, and delete old coverage data. -->
      <unzip src="${test-app.artifact}" dest="${output.dir}" overwrite="true" />
      <delete file="${output.dir}/cobertura.ser" />
    
      <!-- Instrument the jars in-place. Make sure to only capture what you want instrumented! -->
      <cobertura-instrument datafile="${output.dir}/cobertura.ser">
        <fileset dir="${output.dir}/test-app/plugins">
          <include name="**/*our.company_*.jar" />
        </fileset>
      </cobertura-instrument>
    
      <!-- Run the unit test application, by classname rather than by jar. -->
      <java fork="true" classname="org.eclipse.equinox.launcher.Main" logerror="true" failonerror="true" maxmemory="1G">
        <classpath>
          <pathelement location="${output.dir}/test-app/startup.jar" />
          <pathelement location="${tasks.dir}/lib/cobertura/cobertura.jar" />
          <fileset dir="${tasks.dir}/lib/cobertura">
            <include name="**/*.jar" />
          </fileset>
          <pathelement location="${java.class.path}" />
        </classpath>
        <sysproperty key="net.sourceforge.cobertura.datafile" file="${output.dir}/cobertura.ser" />            
        <arg value="-data" />
        <arg value="${output.dir}/test-app/workspace" />
        <arg value="--formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter:${log.dir}/test-results.xml" />
      </java>
    
      <!-- Generate the coverage reports. -->
      <cobertura-report format="html" datafile="${output.dir}/cobertura.ser" destdir="${output.dir}/cobertura-report">
        <fileset dir="${workspace.dir}/plugins">
          <include name="**/*.java" />
        </fileset>
      </cobertura-report>
    </target>
    

    希望这可以帮助与我们在同一个地方的人。

    【讨论】:

    • 太棒了!我们碰巧现在正在做类似的事情。很棒的发现。
    猜你喜欢
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    • 2019-05-18
    • 1970-01-01
    • 2011-10-24
    • 2016-08-18
    相关资源
    最近更新 更多