Jacoco et Unit testent la couverture du Code avec android-gradle-plugin> = 1.1
j'ai récemment commencé à intégrer android-gradle-plugin
1.1.0 dans un de mes projets. Le projet utilise robolectric 2.4
exécuter des tests unitaires.
c'est un projet multi-modules avec des dépendances très complexes (certains modules dépendent d'autres modules). Quelque chose comme ça:
--> application-module (dependsOn: module1, module2, module-core)
--> module1 (dependsOn: module-core)
--> module2 (dependsOn: module-core)
--> module-core (dependsOn: module3, module4)
--> module3 (library dependencies)
--> module4 (library dependencies)
pour une image plus claire veuillez voir jacoco-exemple projet.
j'ai essayé d'intégrer JaCoCo pour générer des rapports pour les tests unitaires, mais il me semble qu'il ne fonctionne que <!--5 qui sont essentiellement des essais d'instrumentation.
après un peu de google, j'ai rencontré quelques projets sur GitHub et d'autres articles, mais ils sont principalement axés sur les versions précédentes du android-gradle-plugin
ou utilisez d'autres plugins tiers comme android-unit-test
par exemple ici.
Peut être que j'ai perdu ma capacité à google. Mais quelqu'un peut m'indiquer une direction où je peux trouver quelques documentations concernant les nouveaux trucs dans le plugin Gradle android et comment exécuter la tâche jacoco uniquement pour les tests unitaires?
UPDATE
a Adopté le script à partir de exemple de nenick:
apply plugin: "jacoco"
configurations {
jacocoReport
}
task jacocoReport(dependsOn: 'testDebug') << {
ant {
taskdef(name:'jacocoreport',
classname: 'org.jacoco.ant.ReportTask',
classpath: configurations.jacocoReport.asPath)
mkdir dir: "${buildDir}/test-coverage-report"
mkdir dir: "${buildDir}/reports/jacoco/test/"
jacocoreport {
executiondata = files("${buildDir}/jacoco/testDebug.exec")
structure(name: "${rootProject.name}") {
classfiles {
fileset (dir: "${buildDir}/intermediates/classes/debug") {
//exclude(name: '**/*_*.class')
exclude(name: '**/R.class')
exclude(name: '**/R$*.class')
exclude(name: '**/BuildConfig.class')
}
}
sourcefiles {
fileset dir: "src/main/java"
fileset dir: "${buildDir}/generated/source/buildConfig/debug"
fileset dir: "${buildDir}/generated/source/r/debug"
}
}
xml destfile: "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
html destdir: "${buildDir}/test-coverage-report/"
}
}
}
dependencies {
jacocoReport 'org.jacoco:org.jacoco.ant:0.7.2.201409121644'
}
Après le ./gradlew jacocoReport
exécute et génère le rapport, mais il affiche 0 (zéro) couverture de test, ce qui est impossible car au moins la moitié de toutes les classes sont testées.
UPDATE_2
Essayé cette exemple. Ajouter la tâche suivante à un de mes fichiers de build gradle:
task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports"
classDirectories = fileTree(
dir: "${buildDir}/intermediates/classes/debug",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
sourceDirectories = files("${buildDir.parent}/src/main/java")
additionalSourceDirs = files([
"${buildDir}/generated/source/buildConfig/debug",
"${buildDir}/generated/source/r/debug"
])
executionData = files("${buildDir}/jacoco/testDebug.exec")
reports {
xml.enabled = true
html.enabled = true
}
}
même problème, les rapports sont générés, mais la couverture du code est toujours zéro.
UPDATE_3
il se connecte que la tâche de UPDATE_2 a fonctionné mais seulement pour le module avec apply plugin: 'com.android.application'
(Les rapports générés correctement). Mais pour les modules qui sont des bibliothèques android (apply plugin: 'com.android.library'
) les rapports montrent une couverture nulle, bien que les modules contiennent plus de tests que l'application module.
UPDATE_4
J'ai créé un projet d'exemple simple qui démontre mon problème. Actuellement si vous courez ./gradlew jacocoReport
le rapport est généré, mais aucune couverture d'essai n'est affichée pour les projets du module. Voir cette lien
brève note: lorsque les tests étaient des AndroidUnitTests (whiteout JUnit 4 et Robolectric) les rapports de JaCoCo montraient une couverture pour tous les modules.
des idées?
9 réponses
après les tracas j'ai décidé de créer un open source Gradle plugin pour que.
Racine de construire.gradle
buildscript {
repositories {
mavenCentral() // optional if you have this one already
}
dependencies {
classpath 'com.vanniktech:gradle-android-junit-jacoco-plugin:0.8.0'
}
}
apply plugin: 'com.vanniktech.android.junit.jacoco'
alors exécutez simplement
./gradlew jacocoTestReportDebug
il exécutera les tests de JUnit en mode Debug puis vous donnera la sortie Jacoco en format xml et html dans le répertoire de compilation correspondant.
il supporte aussi les saveurs. Avoir 2 saveurs rouge et bleu ces tâches serait créé
- jacocoTestReportRedDebug
- jacocoTestReportBlueDebug
- jacocoTestReportRedRelease
- jacocoTestReportBlueRelease
Après quelques recherche supplémentaires, je suis tombé sur ce projet J'ai dû faire quelques modifications pour que la solution puisse fonctionner pour mon type de projet, mais maintenant les rapports de couverture d'essai sont générés correctement.
j'ai poussé les changements adoptés à mon exemple dépôt github dans le cas où quelqu'un va avoir un problème similaire dans l'avenir.
j'ai configuré mes tests unitaires pour gradle 1.2 en utilisant ceci blog. Puis j'ai rassemblé des informations que j'ai trouvées ici et ailleurs pour ajouter de la couverture de code à des modules indépendants au lieu de l'ensemble du projet. Dans mon module de bibliothèque build.gradle
le fichier, j'ai ajouté le code suivant:
apply plugin: 'jacoco'
def jacocoExcludes = [
'com/mylibrary/excludedpackage/**'
]
android {
...
}
android.libraryVariants.all { variant ->
task("test${variant.name.capitalize()}WithCoverage", type: JacocoReport, dependsOn: "test${variant.name.capitalize()}") {
group = 'verification'
description = "Run unit test for the ${variant.name} build with Jacoco code coverage reports."
classDirectories = fileTree(
dir: variant.javaCompile.destinationDir,
excludes: rootProject.ext.jacocoExcludes.plus(jacocoExcludes)
)
sourceDirectories = files(variant.javaCompile.source)
executionData = files("${buildDir}/jacoco/test${variant.name.capitalize()}.exec")
reports {
xml.enabled true
xml.destination "${buildDir}/reports/jacoco/${variant.name}/${variant.name}.xml"
html.destination "${buildDir}/reports/jacoco/${variant.name}/html"
}
}
}
Et dans mon projet build.gradle
le fichier, j'ai ajouté de la commune exclut:
ext.jacocoExcludes = [
'android/**',
'**/*$$*',
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Service.*'
]
en outre, il semble que la couverture du code pour les tests unitaires pourrait être intégrée dans le futur Problème 144664
attention: Ceci est un hack! En utilisant votre configuration ci-dessus, j'ai mis en place un hack pour basculer le plugin android Entre application et bibliothèque en fonction des tâches de construction choisies. Cela fonctionne bien pour moi parce que je ne finis pas par commettre le code avec le mode d'application défini.
// dynamically change the android plugin to application if we are running unit tests or test reports.
project.ext.androidPlugin = 'com.android.library'
for (String taskName : project.gradle.startParameter.taskNames) {
if (taskName.contains('UnitTest') || taskName.contains('jacocoTestReport')) {
project.ext.androidPlugin = 'com.android.application'
break
}
}
logger.lifecycle("Setting android pluging to ${project.ext.androidPlugin}")
apply plugin: project.ext.androidPlugin
...
apply plugin: 'jacoco'
configurations {
jacocoReport
}
task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports"
classDirectories = fileTree(
dir: "${buildDir}/intermediates/classes/debug",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
sourceDirectories = files("${buildDir.parent}/src/main/java")
additionalSourceDirs = files([
"${buildDir}/generated/source/buildConfig/debug",
"${buildDir}/generated/source/r/debug"
])
executionData = files("${buildDir}/jacoco/testDebug.exec")
reports {
xml.enabled = true
html.enabled = true
}
}
espérons que l'équipe des outils android corrigera cela bientôt.
j'ai enfin pu voir mon code de couverture des tests JUnit avec Android Studio 1.1.
jacoco.gradle
apply plugin: 'jacoco'
jacoco {
toolVersion "0.7.1.201405082137"
}
def coverageSourceDirs = [
"$projectDir/src/main/java",
]
task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled = true
html.enabled = true
}
classDirectories = fileTree(
dir: './build/intermediates/classes/debug',
excludes: ['**/R*.class',
'**/*$InjectAdapter.class',
'**/*$ModuleAdapter.class',
'**/*$ViewInjector*.class'
]
)
sourceDirectories = files(coverageSourceDirs)
executionData = files("$buildDir/jacoco/testDebug.exec")
// Bit hacky but fixes https://code.google.com/p/android/issues/detail?id=69174.
// We iterate through the compiled .class tree and rename $$ to $.
doFirst {
new File("$buildDir/intermediates/classes/").eachFileRecurse { file ->
if (file.name.contains('$$')) {
file.renameTo(file.path.replace('$$', '$'))
}
}
}
}
et puis dans la construction.gradle fichier du module (je l'ai mis entre android
et dependencies
):
apply from: '../jacoco.gradle'
dans le defaultConfig
bloc android
. J'ai ajouté ceci (Je ne sais pas si c'est nécessaire, mais j'ai obtenu cela de ce blog):
android {
defaultConfig {
testHandleProfiling true
testFunctionalTest true
}
}
Profiter.
Je résous les problèmes avec JaCoCo et le faire fonctionner avec le dernier plugin Gradle android 1.1.3
Projet avec la dernière gradle scripts: https://github.com/OleksandrKucherenko/meter
Références:
comment joindre sa propre implémentation au lieu de se moquer dans les tests D'Unité Android Studio? https://plus.google.com/117981280628062796190/posts/8jWV22mnqUB
petit conseil pour tous ceux qui essaient D'utiliser la couverture JaCoCo dans android construit... découverte inattendue!!! https://plus.google.com/117981280628062796190/posts/RreU44qmeuP
JaCoCo XML / HTML Report for Unit Testshttps://plus.google.com/u/0/+OleksandrKucherenko / posts/6vNWkkLed3b
je faisais face exactement au même problème que vous. Aujourd'hui, j'ai complètement supprimé android studio, android sdk, gradle. Puis tout réinstaller. Après cela, j'ai juste ajouté à l'intérieur de la construction de l'application.gradle.
debug { testCoverageEnabled true } Puis-je exécuter ./ gradlew connectedChec. Tout fonctionne à la perfection. Studio Android par défaut Jacoco fonctionne très bien pour moi. Je pense qu'il est également possible de créer une tâche jacocoTestReport et ensuite de créer une couverture de code.Je ne sais pas pourquoi gradle et android studio ne fonctionnait pas auparavant.
Vous pouvez essayer d'utiliser ce plugin Gradle: https://github.com/arturdm/jacoco-android-gradle-plugin
en gros, tout ce que vous devez faire est de l'appliquer comme ceci:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
}
}
apply plugin: 'com.android.library' // or 'com.android.application'
apply plugin: 'jacoco-android'
en conséquence, vous devriez obtenir un JacocoReport
tâche pour chaque variante. Exécutez la commande ci-dessous pour générer des rapports de couverture de code pour tous.
$ ./gradlew jacocoTestReport
veuillez créer un exemple et je peux jeter un coup d'oeil. Je suppose que c'est une configuration de chemin manquante.
- inclure tous les fichiers (*.exec)
- ajouter tous vos chemins de sources (module/src/main/java)
- ajouter tous les chemins d'accès (module/build/intermédiaires/classes/debug)
voici deux exemples de ce que cela pourrait être