Тест не пройден при использовании JaCoCO

Я пытаюсь измерить охват с помощью JaCoCo в этом проекте: https://github.com/square/retrofit

Кажется, все работает нормально, но по некоторым причинам несколько тестов, которые раньше работали, терпят неудачу при использовании агента времени выполнения JaCoCo.

Вот (интересная часть) моего pom.xml:

...
<plugins>
   ...
   <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.17</version>
      <executions>
         <execution>
            <id>default-test</id>
            <phase>test</phase>
            <goals>
               <goal>test</goal>
            </goals>
         </execution>
      </executions>
      <configuration>
         <!-- Sets the VM argument line used when unit tests are run. -->
         <argLine>${surefireArgLine}</argLine>
      </configuration>
   </plugin>
   ...
   <plugin>
      <groupId>org.jacoco</groupId>
      <artifactId>jacoco-maven-plugin</artifactId>
      <version>0.8.0</version>
      <executions>
         <!--
            Prepares the property pointing to the JaCoCo runtime agent which
            is passed as VM argument when Maven the Surefire plugin is executed.
        -->
         <execution>
            <id>pre-unit-test</id>
            <goals>
               <goal>prepare-agent</goal>
            </goals>
            <configuration>
               <!--
                    Sets the name of the property containing the settings
                    for JaCoCo runtime agent.
                -->
               <propertyName>surefireArgLine</propertyName>
            </configuration>
         </execution>
         <!--
            Ensures that the code coverage report for unit tests is created after
            unit tests have been run.
        -->
         <execution>
            <id>post-unit-test</id>
            <phase>test</phase>
            <goals>
               <goal>report</goal>
            </goals>
         </execution>
      </executions>
   </plugin>
   ...
</plugins>

Полный pom.xml можно найти здесь: https://pastebin.com/HSKJpS3g

Все тесты терпят неудачу по той же причине, позвольте мне показать пример. Рассмотрим класс Example заявлено в этом тесте:

@Test public void customMethodNoBody() {
    class Example {
      @HTTP(method = "CUSTOM1", path = "/foo")
      Call<ResponseBody> method() {
        return null;
      }
    }

    /* Do some operations with the class Example */
  }

Позже в коде Exemple.class передается в метод TestingUtils.onlyMethod который выдаст исключение:

package retrofit2;

import java.lang.reflect.Method;

public final class TestingUtils {
  public static Method onlyMethod(Class c) {
    Method[] declaredMethods = c.getDeclaredMethods();
    if (declaredMethods.length == 1) {
      return declaredMethods[0];
    }
    throw new IllegalArgumentException("More than one method declared.");
  }
}

Все тесты не выполняются для этого исключения, чего не было до добавления JaCoCo. Почему это происходит? Как я могу решить проблему?

Команда, используемая maven для запуска тестов:

/usr/lib/jvm/java-8-oracle/jre/bin/java
-javaagent:/root/.m2/repository/org/jacoco/org.jacoco.agent/0.7.5.201505241946/org.jacoco.agent-0.7.5.201505241946-runtime.jar=destfile=/root/retrofit/retrofit/target/jacoco.exec
-jar /root/retrofit/retrofit/target/surefire/surefirebooter7714471086789859732.jar
/root/retrofit/retrofit/target/surefire/surefire2679778491836039056tmp
/root/retrofit/retrofit/target/surefire/surefire_02232907551688610770tmp

Обратите внимание -javaagent опция добавлена ​​JaCoCo. Если вы хотите просмотреть все журналы, выпущенные mvn clean testВы можете найти их здесь: https://pastebin.com/kUtLtyjw

1 ответ

Решение

При использовании JaCoCo вы хотите, чтобы синтаксические поля и методы не обрабатывались вашим собственным кодом, поскольку JaCoCo использует их для сбора статистики покрытия. К счастью, оба Field а также Method иметь isSynthetic() метод.

public static Method onlyMethod(Class c) {
  return Arrays.stream(c.getDeclaredMethods())
    .filter(m -> !m.isSynthetic())
    .reduce((a, b) -> {
        throw new IllegalStateException("More than one method declared.");
    })
    .get();
}
Другие вопросы по тегам