Проблемы с отчетом о покрытии Jacoco

Я пытаюсь определить место, где jacoco создаст файл покрытия для инструментальных тестов, работающих на реальных устройствах.

Из --debug запуска задачи gradle я вижу этот журнал:

[DEBUG] [org.gradle.api.Task] DeviceConnector 'Nexus 5X - 6.0.1': installing /home/martin/workspace/lib/my-lib/build/outputs/apk/my-lib-debug-androidTest-unaligned.apk
[INFO] [org.gradle.api.Task] Starting 1 tests on Nexus 5X - 6.0.1
[INFO] [org.gradle.api.Task]  de.my.lib.utils.UtilsTest testMyTest[Nexus 5X - 6.0.1] [32mSUCCESS [0m
[DEBUG] [org.gradle.api.Task] DeviceConnector 'Nexus 5X - 6.0.1': fetching coverage data from /data/data/de.my.lib.test/coverage.ec
[DEBUG] [org.gradle.api.Task] DeviceConnector 'Nexus 5X - 6.0.1': uninstalling de.my.lib.test 13:46:14.538
[DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':my-lib:connectedDebugAndroidTest'

Я пробовал 3 способа определить местоположение:

Использование тега <instrumentation> в файле манифеста ничего не изменило.

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="de.my.lib.test"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <instrumentation
        android:name="android.support.test.runner.AndroidJUnitRunner"
        xmlns:tools="http://schemas.android.com/tools"
        android:targetPackage="de.my.lib.test"
        tools:replace="android:targetPackage">
        <meta-data
            android:name="coverage"
            android:value="true" />
        <meta-data
            android:name="coverageFile"
            android:value="/sdcard/coverage.ec" />
    </instrumentation>
</manifest>

Я попробовал это с gradle, но результат был таким же:

defaultConfig {
    // unimportant stuff
    testApplicationId "de.my.lib.test"

    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    testInstrumentationRunnerArgument('coverageFile', '/sdcard/coverage.ec')
}

И, наконец, я попробовал это с помощью команды adb:

adb shell am instrument -w -e coverage true -e coverageFile /sdcard/coverage.ec de.my.lib.test/android.support.test.runner.AndroidJUnitRunner

Но там я получаю 2 ошибки:

de.my.lib.utils.UtilsTest:. Не удалось найти класс: org.jacoco.agent.rt.internal_773e439.CoverageTransformer. Время: 0,072

ОК (1 тест)

Ошибка: не удалось создать покрытие emma.

Я здесь совершенно потерян. Любые идеи?

Общие сведения Почему мне нужно, чтобы он хранился в другом месте: существует ошибка с командой adb shell run-as на некоторых устройствах и в версии Android, поэтому в моей ферме тестовых устройств есть устройства, которые возвращают 0% покрытия, поскольку файл нельзя тянуть. Поэтому мне нужно, чтобы файл хранился в общедоступном месте.


person WarrenFaith    schedule 04.02.2016    source источник


Ответы (3)


Однако отчет о покрытии еще не сформирован. Чтобы включить эту опцию, нам нужно добавить свойство в наш вариант отладочной сборки. Используя DSL плагина Android, мы можем включить покрытие через свойство testCoverageEnabled:

android {
    ...
    buildTypes {
        debug {
            testCoverageEnabled true
        }
        ...
    }
}

Чтобы включить отчет о покрытии для локальных тестов при использовании версии 2.2.+ плагина Android Gradle, вам необходимо включить его в build.gradle вашего приложения:

android {
    //...

    testOptions {
        unitTests.all {
            jacoco {
                includeNoLocationClasses = true
            }
        }
    }
}

Инструментарий, выполняемый Jacoco, создает исполняемые файлы, содержащие необходимые данные для создания отчета (HTML, XML и т. д.). Проблема здесь в том, что Espresso генерирует файл .ec, а выполнение модульных тестов генерирует файл .exec… у нас разные форматы!

Поскольку мы не можем настроить задачу покрытия эспрессо, мы должны сначала убедиться, что она выполняется. Далее нам нужно запустить модульные тесты, а затем создать данные о покрытии с обоими файлами (ec и exec).

Чтобы включить это, нам нужно еще раз отредактировать нашу задачу и добавить файл coverage.ec в качестве параметра в свойство executionData:

apply plugin: 'jacoco'

task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {

    reports {
        xml.enabled = true
        html.enabled = true
    }

    def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
    def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/debug", excludes: fileFilter)
    def mainSrc = "${project.projectDir}/src/main/java"

    sourceDirectories = files([mainSrc])
    classDirectories = files([debugTree])
    executionData = fileTree(dir: "$buildDir", includes: [
            "jacoco/testDebugUnitTest.exec", 
            "outputs/code-coverage/connected/*coverage.ec"
    ])
}

Поскольку плагин Android Gradle 2.2.+ теперь генерирует файл покрытия для каждого выполнения, используя устройство/эмулятор в имени файла, теперь нам нужно передать каждый файл в данные выполнения, так как имя файла теперь динамическое. Кроме того, я добавил задачу createDebugCoverageReport в качестве зависимости от нашей пользовательской задачи, поэтому нам не нужно запускать ее вручную :)

Наконец, когда мы выполним обе задачи, запустив сначала тесты Espresso, мы получим унифицированный отчет о покрытии!

gradle clean jacocoTestReport

Подробное объяснение см. в разделе здесь.

Редактировать:

Итак, команда adb shell am instrument не генерирует отчет, для этого вам нужно обработать его с помощью решения gradle. Если вы действительно хотите проверить это самостоятельно, вам нужно использовать настраиваемый бегун.

Рекомендации:

1) Как автоматически создать отчет о тестировании Android в HTML

2) Как получить результаты теста при использовании adb инструмент оболочки

3) https://github.com/jsankey/android-junit-report


Проверить из командной строки


Обновлен до метода командной строки, следуйте этим шагам. .

Запуск инструментированного приложения

После того, как у нас есть класс EmmaInstrumentation (находится в ref link), нам нужно еще несколько настроек, чтобы иметь возможность получить отчет о покрытии работающего приложения.

Во-первых, нам нужно добавить новую активность в манифест. Во-вторых, мы должны разрешить нашему приложению записывать на SD-карту, если именно здесь мы решили сгенерировать отчет о покрытии. Для этого вы должны предоставить разрешение android.permission.WRITE_EXTERNAL_STORAGE. Затем пришло время собрать и установить инструментированный apk:

$ ant clean
$ ant instrument
$ ant installi

Все готово для запуска инструментированного приложения

$ adb shell am instrument -e coverage true \
    -w com.example.i2at.tc/\
        com.example.instrumentation.EmmaInstrumentation

Здесь находится исходный код.

person 5377037    schedule 18.02.2019
comment
Нет, не по пути градиента, а от "adb shell am instrument..." - person TheLittleNaruto; 18.02.2019
comment
Идея состоит в том, чтобы получить его через командную строку, так как мы тестируем системные приложения. он использует файл mk для создания сборки, в отличие от обычного способа, то есть с использованием сценария gradle. - person TheLittleNaruto; 18.02.2019
comment
@TheLittleNaruto Я обновил свой ответ, пожалуйста, посмотрите, если он вам поможет. - person 5377037; 21.02.2019
comment
Спасибо, что приложил слишком много усилий. Но мы не используем ant. Кроме того, все, что вы упомянули, мы уже пробовали. - person TheLittleNaruto; 21.02.2019
comment
Я понял первопричину. Опубликовал ответ. Проверьте один раз. - person TheLittleNaruto; 24.02.2019

отсутствующий CoverageTransformer указывает на отсутствие зависимости от среды выполнения агента JaCoCo. один простой подход к решению может заключаться в том, чтобы предоставить ему то, что он требует (чтобы он был доступен на устройстве):

testImplementation "org.jacoco:org.jacoco.agent:0.8.3"

в случае, если вы получите FileNotFoundException, когда ClassNotFoundException был исправлен, убедитесь, что у вас есть разрешение на запись на SD-карту, что, по-видимому, является еще одной возможной ловушкой:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

как я только что видел, существует также org.jacoco .report, который можно добавить дополнительно:

testImplementation "org.jacoco:org.jacoco.report:0.8.3"

пакет org.jacoco.agent в каждом случае содержит класс CoverageTransformer.

person Martin Zeitler    schedule 24.02.2019

Для нас это было приложение AOSP. Мы создавали тестовые и модульные apks с отключением компилятора Jack, что вызывало эту дополнительную проблему. Потому что нам нужен был компилятор Jack для генерации coverage.em. Но ошибка была не совсем актуальной. Так что не было никакого понятия, чтобы идти дальше.

Поэтому исправление состояло в том, чтобы запустить сервер компилятора jack и получить сгенерированные с его помощью APK-файлы.

person TheLittleNaruto    schedule 24.02.2019
comment
как этот ответ связан с сообщением об ошибке в вопросе? нет ни единого слова о том, что coverage.em не найдено, но CoverageTransformer не найдено. - person Martin Zeitler; 24.02.2019
comment
Прочтите ответ еще раз. @MartinZeitler Ошибка была такой же, как и в вопросе. - person TheLittleNaruto; 24.02.2019
comment
@TheLittleNaruto Я проверяю, что ваш ответ касается выпуска приложения после выпуска, хотя в вопросе об этом не упоминается; это говорит только об отладке приложения, поэтому мой ответ был основан на этом. Кстати, я чувствую себя счастливым; вы исправили свою проблему. - person 5377037; 24.02.2019