【问题标题】:How do I exclude classes from being instrumented by the maven-emma plugin?如何排除类被 maven-emma 插件检测?
【发布时间】:2012-03-19 03:32:33
【问题描述】:

我有一些单元测试(虽然它们是 Android 测试,但我使用的是 Robolectric,所以它们在 JVM 上运行)。他们在没有覆盖的情况下快乐地奔跑。

当我尝试覆盖时,我从 emma-maven 收到此错误:

org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:emma-maven-plugin:1.0-alpha-3:instrument (default-cli) on project android: Execution default-cli of goal org.codehaus.mojo:emma-maven-plugin:1.0-alpha-3:instrument failed: class [com.larvalabs.svgandroid.ParserHelper] appears to be instrumented already

重要的是class .... appears to be instrumented already

很难找到合适的文档,但这是我从各种来源拼凑起来的配置:

<plugin>
    <!-- This doesn't work, see below for a working configuration -->
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>emma-maven-plugin</artifactId>
    <version>1.0-alpha-3</version>
    <inherited>true</inherited>                          
    <executions>
            <execution>
                    <phase>process-classes</phase>                               
                    <configuration>
                            <filters>
                                    <filter>-com.viewpagerindicator.*</filter>
                                    <filter>-com.actionbarsherlock.*</filter>
                                    <filter>-com.larvalabs.svgandroid.*</filter>
                            </filters>
                    </configuration>
                    <goals> 
                            <goal>instrument</goal>
                    </goals>
            </execution>
    </executions>
</plugin>

问题是,排除了它抱怨的那些包(我认为问题在于这些是 Android 库项目无意中在某些路径列表上结束了两次),它现在抱怨我自己的包。


一位同事错误地建议上面的 部分应该放在 中。

原来应该直接在中,剩下的位应该去掉,看答案。

【问题讨论】:

  • 您能否详细介绍一下您的项目结构,您是否创建了自己的库项目,是否将 svg android 添加到您的库和主项目依赖项中?
  • 事实证明,“已检测”错误是由“执行”元素安排除默认执行之外的检测目标的非默认执行引起的。取出显式阶段将配置默认阶段。我是从几个例子中拼凑出来的,其中一个是试图以一种不适用于我的情况的特定方式添加覆盖范围。

标签: android plugins maven emma


【解决方案1】:

请使用模式=“覆盖”。它会工作得很好。

【讨论】:

    【解决方案2】:

    我找到了一个解决方案 - 非常简单。

    忘记 pluginManagement 的东西:只有通过忽略 /this/ pom 的过滤器才能“起作用”,但将它们应用于任何子 pom:http://maven.apache.org/pom.html#Plugin_Management

    只需将配置元素移出执行块,然后删除执行块。 http://maven.apache.org/guides/mini/guide-configuring-plugins.html#Generic_Configuration

    配置部分直接位于插件元素内,使用“mvn -X emma:emma”运行会显示列出的过滤器。由于每个排除行都改变了我看到的错误,我推断它是排除的。 (我认为包括在内,您添加带有 + 前缀的过滤器以覆盖上述 - 前缀的部分。)

    <project>
     <build>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>emma-maven-plugin</artifactId>
        <version>1.0-alpha-3</version>
        <!-- inherited>true</inherited -->
        <configuration>
                <filters>
                        <filter>-com.viewpagerindicator.*</filter>
                        <filter>-com.actionbarsherlock.*</filter>
                        <filter>-com.larvalabs.svgandroid.*</filter>
                </filters>
                <!-- verbose>true</verbose -->
       </configuration>
      </plugin>
    

    就问题的隐含 Android 部分而言(这实际上使过滤对我来说毫无意义),因为 Android 需要一个单独的 APK 来保存测试并运行主应用程序 APK,所以您根本不运行 Android来自同一项目的集成测试:android 插件希望您从单独的项目中制作集成测试 APK - 通常是同一父 pom 文件下的兄弟。在 zip 中隐藏了 android 插件页面上的示例/示例项目 - http://code.google.com/p/maven-android-plugin/wiki/Samples - 您应该在其中搜索“coverage”并将其更改为:

    <coverage>true</coverage>
    

    到配置 - 几个样本有它,但被注释掉了。我分心了,所以不记得这是否有效,但显然应该有效。

    由于我们不想在项目的现有源代码管理中插入目录级别,因此我们创建了名为“父”和“集成”的目录作为应用程序 pom.xml 的对等目录,使用“父”来保存父 pom , 和 'integration' 用于集成测试,本节告诉 app/pom.xml 使用 app/parent/pom.xml:

    <project>
        <parent>
                <groupId>our.group.id</groupId>
                <artifactId>base</artifactId>
                <relativePath>parent</relativePath>
                <version>3.9.0</version>
        </parent>
    

    这在 app/integration/pom.xml 中:

    <project>
      <parent>
        <groupId>our.group.id</groupId>
        <artifactId>base</artifactId>
        <relativePath>../parent</relativePath>
        <version>3.9.0</version>
      </parent>
    

    【讨论】:

    • 请做,如果你能显示最终配置会很好,因为上面的描述确实让我很困惑;)
    • 已更新,抱歉。评论说如果上面的配置让你满意,我会认为自己赢得了你的赏金并勾选我的答案。
    • 另外,我没有更新,因为我在试图弄清楚包含和排除如何相互影响时分心,因为......虽然排除有效,但它看起来有点像将包含与排除混合在一起(例如允许所有,排除 com.foo.*,但允许 com.foo.interesting.* 尽管排除 - +*-com.foo.*+com .foo.interesting.*) 对我不起作用。
    • 抱歉,您的设置无法与我的设置一起使用。我现在根据需要调整了 android maven 插件 emma wiki code.google.com/p/maven-android-plugin/wiki/EmmaMaven
    【解决方案3】:

    据我了解,只有 cobertura 需要检测类来生成报告。如果你在 target/classes 中创建它们,它们会覆盖原来的类文件。

    如果您因此需要 jar 中的检测文件,您可以配置 maven-jar-plugin to pick up target/generated-classes 目录中的文件,而不是标准 ${build.project.输出目录}。

    编辑

    查看 maven-jar-plugin 描述。要仅使用目标/生成类,您的 POM 中的以下添加应该可以工作 - 尝试并根据您的需要进行修改:

    <project>
      ...
      <build>
        <plugins>
          ...
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.3</version> <!-- replace with correct version nbr! -->
            <configuration>
              <includes>
                <include>${project.build.directory}/generated-classes/**/*.class</include>
              </includes>
              <excludes>
                <exclude>${project.build.directory}/classes/**/*.class</include>
              </excludes>
    
            </configuration>
          </plugin>
          ...
        </plugins>
      </build>
      ...
    </project>
    

    ${project.build.directory} 指向您的目标文件夹,${project.build.ouputDirectory} 指向目标/类。我不知道你是否可以简单地将${project.build.ouputDirectory} 设置为一个新值 - 看看this chapter of the maven book,也许你会找到一些提示

    参考:

    coberture:instrument 完成后,您也可以使用 maven 将文件从目标/生成类复制到目标/类。 This question 有一个示例 POM(片段)的答案,您只需要确定正确的阶段(流程资源对于您的情况来说绝对为时过早)

    还有Refer this

    希望对您有所帮助!

    【讨论】:

    • 但问题是关于 Emma,而不是 Cobertura?也就是说,可能只有 Android 才能让 Emma 活着,因为它似乎已经无法维护了。
    猜你喜欢
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多