[JAVA] Méditez la querelle entre Power Mock et Jacoco avec Gradle

Aperçu

Viser une couverture 100% java UT avec un certain PJ Lorsque j'ai créé un rapport de couverture avec jacoco, test_coverage.png Ce sera de 0% à tous les niveaux.

Apparemment, Jacoco n'aime pas le powermock, un homme brutal ... Cela dit, la dépendance au powermock est une mort.

solution de contournement

https://github.com/powermock/powermock/wiki/Code-coverage-with-JaCoCo

Second way to get code coverage with JaCoCo - use offline Instrumentation.

Instrumentation apparemment hors ligne. Il n'y a qu'un exemple d'implémentation dans Maven et il n'y a pas beaucoup d'article sur la façon d'écrire dans Gradle, alors écrivons-le.

Dépendances

build.gradle


dependencies {
  testCompile group: 'org.mockito', name: 'mockito-core', version: '2.2.7'
  testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0-beta.5'
  testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0-beta.5'

  jacoco group: 'org.jacoco', name: 'org.jacoco.ant', version: '0.8.2', classifier: 'nodeps'
  jacocoRuntime group: 'org.jacoco', name: 'org.jacoco.agent', version: '0.8.2', classifier: 'runtime'
}

À propos, veuillez noter que l'instrumentation hors ligne semble fonctionner après la version 1.6.6 de powermock.

Offline Instrumentation

build.gradle


configurations {
  jacoco
  jacocoRuntime
}

task instrument(dependsOn: ['classes']) {
  ext.outputDir = buildDir.path + '/classes-instrumented'
  doLast {
    ant.taskdef(name: 'instrument',
                classname: 'org.jacoco.ant.InstrumentTask',
                classpath: configurations.jacoco.asPath)
    ant.instrument(destdir: outputDir) {
      fileset(dir: sourceSets.main.output.classesDir)
    }
  }
}

gradle.taskGraph.whenReady { graph ->
  if (graph.hasTask(instrument)) {
    tasks.withType(Test) {
      doFirst {
        systemProperty 'jacoco-agent.destfile', buildDir.path + '/jacoco/jacoco-coverage.exec'
        classpath = files(instrument.outputDir) + classpath + configurations.jacocoRuntime
      }
    }
  }
}

task report(dependsOn: ['instrument', 'test']) {
  doLast {
    ant.taskdef(name: 'report',
                classname: 'org.jacoco.ant.ReportTask',
                classpath: configurations.jacoco.asPath)
    ant.report() {
      executiondata {
        ant.file(file: buildDir.path + '/jacoco/jacoco-coverage.exec')
      }
      structure(name: 'Example') {
         classfiles {
           fileset(dir: sourceSets.main.output.classesDir)
         }
         sourcefiles {
           fileset(dir: 'src/main/java')
         }
      }
      html(destdir: buildDir.path + '/reports/jacoco/test/html')
    }
  }
}

Immédiatement après la compilation, il est instrumenté et cela ressemble à test + jacoco. Maintenant, quand j'essaye d'exécuter la tâche rapport,

coverage_after.png

PowerMock et jacoco ont été réconciliés avec succès.

Impressions

Je ne comprends pas vraiment ce que fait encore l'instrument. En fait, il s'agit d'une configuration multi-projets, donc j'aimerais combiner les rapports de couverture.

Alors la prochaine fois, j'essaierai de combiner divers documents dans un multi-projet.

Recommended Posts

Méditez la querelle entre Power Mock et Jacoco avec Gradle
Mock le constructeur avec PowerMock
[Java] Vérifiez la différence entre orElse et orElseGet avec IntStream
La différence entre la programmation qui utilise des classes Ruby et la programmation qui n'utilise pas
Organiser la relation entre SLF4J, Logback et Log4J ainsi que leur comportement
À propos de la différence entre irb et pry
Téléchargez JDK avec Gradle et créez JRE
[Java] Comprendre la différence entre List et Set
[iOS] Comprendre la différence entre le cadre et les limites
[Rails / Active Record] À propos de la différence entre créer et créer!
Créez et testez des applications Java + Gradle avec Wercker
Comprenez la différence entre les classes abstraites et les interfaces!
Quelle est la différence entre SimpleDateFormat et DateTimeFormatter? ??
Résumer les différences entre l'écriture C # et Java
Apprenez le mécanisme rudimentaire et l'utilisation de Gradle 4.4
Distinguer les entiers et les fractions avec des expressions régulières
[Swift] NS Predicate ne peut pas faire la distinction entre pleine largeur et demi-largeur