Покрытие тестового кода Android с помощью плагина JaCoCo Gradle
Я новичок в тестировании Gradle и Android, но я уже конвертировал свой проект Android для сборки с Gradle.
Сейчас я пытаюсь выполнить тестовое покрытие проекта Android с помощью плагина Gradle JaCoCo.
Я добавил следующее в мой файл build.gradle:
apply plugin: 'jacoco'
И когда я запускаю "gradle jacocoTestReport" следующую ошибку:
Task 'jacocoTestReport' not found in root project '<project name>'.
Из документации я должен также применить плагин "Java", но он конфликтует с плагином "Android".
Это можно обойти?
Заранее спасибо.
4 ответа
Вот как я пользуюсь Jacoco
:
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.+'
classpath 'org.robolectric:robolectric-gradle-plugin:0.11.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'robolectric'
apply plugin: 'jacoco'
android {
compileSdkVersion 20
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "YOUR_PACKAGE_NAME"
minSdkVersion 10
targetSdkVersion 20
testHandleProfiling true
testFunctionalTest true
}
buildTypes {
debug {
testCoverageEnabled false
}
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
jacoco {
version "0.7.1.201405082137"
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/dependencies.txt'
exclude 'META-INF/LGPL2.1'
exclude 'META-INF/services/javax.annotation.processing.Processor'
exclude 'LICENSE.txt'
}
}
robolectric {
include '**/*Test.class'
exclude '**/espresso/**/*.class'
maxHeapSize "2048m"
}
jacoco {
toolVersion "0.7.1.201405082137"
}
// Define coverage source.
// If you have rs/aidl etc... add them here.
def coverageSourceDirs = [
'src/main/java',
]
task jacocoTestReport(type: JacocoReport, dependsOn: "connectedDebugAndroidTest") {
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('$$', '$'))
}
}
}
}
dependencies {
androidTestCompile('junit:junit:4.11') {
exclude module: 'hamcrest-core'
}
androidTestCompile('org.robolectric:robolectric:2.3') {
exclude module: 'classworlds'
exclude module: 'maven-artifact'
exclude module: 'maven-artifact-manager'
exclude module: 'maven-error-diagnostics'
exclude module: 'maven-model'
exclude module: 'maven-plugin-registry'
exclude module: 'maven-profile'
exclude module: 'maven-project'
exclude module: 'maven-settings'
exclude module: 'nekohtml'
exclude module: 'plexus-container-default'
exclude module: 'plexus-interpolation'
exclude module: 'plexus-utils'
exclude module: 'wagon-file'
exclude module: 'wagon-http-lightweight'
exclude module: 'wagon-http-shared'
exclude module: 'wagon-provider-api'
exclude group: 'com.android.support', module: 'support-v4'
}
}
Приведенный выше код также содержит обходной путь для https://code.google.com/p/android/issues/detail?id=69174.
Более подробная информация: http://chrisjenx.com/gradle-robolectric-jacoco-dagger/
Я использую JaCoCo с проектом, использующим RoboGuice, Butterknife и Robolectric. Мне удалось настроить его с помощью решения @Hieu Rocker, однако были некоторые незначительные недостатки, т. Е. В нашем проекте мы использовали разновидности и у нас есть несколько дополнительных тестов для этих разновидностей, а также дополнительный Java-код для каждого из них. Мы также используем разные типы сборки. Поэтому решение, основанное на задаче testDebug, оказалось недостаточно хорошим. Вот мое решение: в build.gradle в модуле приложения добавьте
apply from: '../app/jacoco.gradle'
Затем создайте файл jacoco.gradle внутри модуля приложения со следующим содержимым:
применить плагин: 'jacoco' jacoco { toolVersion "0.7.1.201405082137" } def getFlavorFromVariant(String variableName) { def flavourString = variableName.replaceAll(/(.*)([AZ].*)/) {все, flavName, buildTypeName -> flavourName } return flavourString; } def getBuildTypeFromVariant(String variableName) {def buildTypeString = variableName.replaceAll(/(.*)([AZ].*)/) { all, flavName, buildTypeName -> "${buildTypeName.toLowerCase()}" } вернуть buildTypeString; } def getFullTestTaskName(String variableName) { return "test${variableName.capitalize()}UnitTest"; } android.applicationVariants.all {option -> def variableName = variable.name; def flavourFromVariant = getFlavorFromVariant ("$ {variableName}"); def buildTypeFromVariant = getBuildTypeFromVariant ("$ {variableName}"); def testTaskName = getFullTestTaskName("${variableName}") task ("jacoco${variableName.capitalize()}TestReport", тип: JacocoReport, depenOn: testTaskName) { group = "Reporting" description = "Создание отчетов покрытия JaCoCo после выполнения тесты для варианта: ${variableName}. " reports {xml.enabled = true html.enabled = true} classDirectories = fileTree (dir: "./build/intermediates/classes/$ndomflavorFromVariant‹/$ndombuildTypeFromVariant}", исключая: ['**/R*.class', '**/*$InjectAdapter.class', '**/*$ModuleAdapter.class', '**/*$ViewInjector*.class' ]) logger.info("Настройка JaCoCo для флейвора: ${flavourFromVariant" }, buildType: ${buildTypeFromVariant}, задача: ${testTaskName}"); def coatingSourceDirs = [ '../app/src/main/java', "../app/src/$ndomflavorFromVariant‹/java" ] sourceDirectories = files(coverSourceDirs) executeData = files("$buildDir/jacoco/${testTaskName}.exec") // Немного странно, но исправляет https://code.google.com/p/android/issues/detail?id=69174. // Итерируем скомпилированное дерево.class и переименовываем $$ в $. doFirst {новый файл ("$ buildDir / промежуточные / классы /").eachFileRecurse { file -> if (file.name.contains('$$')) { file.renameTo(file.path.replace('$$'), '$')) } } } } }
Вы можете выполнить его из командной строки следующим образом:
.gradlew jacocoFlavor1DebugTestReport
или же
.gradlew jacocoOtherflavorPrereleaseTestReport
В нашем проекте мы используем соглашение не использовать заглавную букву внутри имен разновидностей и типов сборки, но если ваш проект не следует этому соглашению, вы можете просто изменить функции getFlavorFromVariant(..) и getBuildTypeFromVariant(..)
Надеюсь, это поможет кому-то
Вы можете попробовать использовать этот плагин Gradle: https://github.com/arturdm/jacoco-android-gradle-plugin
В ответе есть еще немного /questions/5621945/kodovoe-pokryitie-jacoco-i-modulnyih-testov-s-pomoschyu-android-gradle-plugin-11/5621963#5621963.
Вы пытались добавить следующее:
jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)
}
И тогда вместо запуска ./gradlew jacocoTestReport
бежать ./gradlew test jacocoTestReport
,
Если все идет хорошо, вы должны найти результаты теста на build/reports/jacoco/test/html/index.html
,