From 7523619afa1376845708913809a3b25097aa25d4 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 Feb 2023 14:10:32 +0100 Subject: [PATCH] [#673] process .ec files from emulator.wtf Co-authored-by: Carter Jernigan Co-authored-by: Honza --- .../secant.jacoco-conventions.gradle.kts | 39 +++++++++++++++++++ crash-android-lib/build.gradle.kts | 1 + crash-lib/build.gradle.kts | 1 - docs/testing/Testing.md | 10 ++++- preference-impl-android-lib/build.gradle.kts | 1 + sdk-ext-lib/build.gradle.kts | 1 + sdk-ext-ui-lib/build.gradle.kts | 1 + settings.gradle.kts | 1 + spackle-android-lib/build.gradle.kts | 1 + test-lib/build.gradle.kts | 1 + ui-design-lib/build.gradle.kts | 1 + ui-integration-test/build.gradle.kts | 1 + ui-lib/build.gradle.kts | 3 ++ .../src/main/AndroidManifest.xml | 4 ++ 14 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 build-conventions-secant/src/main/kotlin/secant.jacoco-conventions.gradle.kts diff --git a/build-conventions-secant/src/main/kotlin/secant.jacoco-conventions.gradle.kts b/build-conventions-secant/src/main/kotlin/secant.jacoco-conventions.gradle.kts new file mode 100644 index 00000000..abef0b9a --- /dev/null +++ b/build-conventions-secant/src/main/kotlin/secant.jacoco-conventions.gradle.kts @@ -0,0 +1,39 @@ +plugins { + id("jacoco") +} + +tasks { + register("jacocoReport", JacocoReport::class) { + group = "Coverage" + description = "Generate XML/HTML code coverage reports for coverage.ec" + + reports { + xml.required.set(false) + html.required.set(true) + } + + sourceDirectories.setFrom("${project.projectDir}/src/main/kotlin") + val fileFilter = + listOf("**/R.class", "**/R$*.class", "**/BuildConfig.*", "**/Manifest*.*", "**/*Test*.*", "android/**/*.*") + + classDirectories.setFrom( + files("${buildDir}/intermediates/javac/debug").map { + fileTree(it) { + exclude(fileFilter) + } + }, + files("${buildDir}/tmp/kotlin-classes/debug").map { + fileTree(it) { + exclude(fileFilter) + } + }) + + executionData.setFrom( + files("${buildDir}/test-results").map { + fileTree(it) { + include("**/*.ec", "**/*.exec") + } + } + ) + } +} diff --git a/crash-android-lib/build.gradle.kts b/crash-android-lib/build.gradle.kts index 81636e46..aed11c7e 100644 --- a/crash-android-lib/build.gradle.kts +++ b/crash-android-lib/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("secant.android-build-conventions") id("wtf.emulator.gradle") id("secant.emulator-wtf-conventions") + id("secant.jacoco-conventions") } // Note that we force enable test orchestrator for this module, because some of the test cases require it. diff --git a/crash-lib/build.gradle.kts b/crash-lib/build.gradle.kts index 98969886..6b962287 100644 --- a/crash-lib/build.gradle.kts +++ b/crash-lib/build.gradle.kts @@ -2,7 +2,6 @@ plugins { kotlin("multiplatform") id("secant.kotlin-multiplatform-build-conventions") id("secant.dependency-conventions") - id("secant.android-build-conventions") } kotlin { diff --git a/docs/testing/Testing.md b/docs/testing/Testing.md index a738d8bc..a0777100 100644 --- a/docs/testing/Testing.md +++ b/docs/testing/Testing.md @@ -23,10 +23,18 @@ The app consists of different Gradle module types (e.g. Kotlin Multiplatform, An Kotlin Multiplatform does not support coverage for all platforms. Most of our code lives under commonMain, with a JVM target. This effectively allows generation of coverage reports with Jacoco. Coverage is enabled by default when running `./gradlew check`. ### Android -The Android Gradle plugin supports code coverage with Jacoco. This integration can sometimes be buggy. For that reason, coverage is disabled by default and can be enabled on a case-by-case basis, by passing `-PIS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED=true` as a command line argument for Gradle builds. For example: `./gradlew connectedCheck -PIS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED=true`. +The Android Gradle plugin supports code coverage with Jacoco. This integration can sometimes be buggy. For that reason, coverage is disabled by default and can be enabled on a case-by-case basis, by setting the property `IS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED=true`. For example: `./gradlew connectedCheck -PIS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED=true`. When coverage is enabled, running instrumentation tests will automatically generate coverage reports stored under `$module/build/reports/coverage`. +### Generating code coverage locally +- `./gradlew :connectedCheck -PIS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED=true` for Android modules. These modules internally use JaCoCo to generate test coverage. +- `./gradlew :check` for Kotlin modules. These modules internally use Kover to generate test coverage. + +### Generating code coverage with emulator.wtf +1. `./gradlew :testDebugWithEmulatorWtf -PIS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED=true` +1. `./gradlew :jacocoReport`. The command above only generates `.ec` files, so this separate Gradle task is needed to convert those into a human-readable report. + ## Benchmarking This section provides information about available benchmark tests integrated in this project as well as how to use them. Currently, we support macrobenchmark tests run locally as described in the Android [documentation](https://developer.android.com/topic/performance/benchmarking/benchmarking-overview). diff --git a/preference-impl-android-lib/build.gradle.kts b/preference-impl-android-lib/build.gradle.kts index a4b78729..d749660a 100644 --- a/preference-impl-android-lib/build.gradle.kts +++ b/preference-impl-android-lib/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("secant.android-build-conventions") id("wtf.emulator.gradle") id("secant.emulator-wtf-conventions") + id("secant.jacoco-conventions") } // Force orchestrator to be used for this module, because we need the preference files diff --git a/sdk-ext-lib/build.gradle.kts b/sdk-ext-lib/build.gradle.kts index ff0c0f05..ddf2485c 100644 --- a/sdk-ext-lib/build.gradle.kts +++ b/sdk-ext-lib/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("secant.android-build-conventions") id("wtf.emulator.gradle") id("secant.emulator-wtf-conventions") + id("secant.jacoco-conventions") } android { diff --git a/sdk-ext-ui-lib/build.gradle.kts b/sdk-ext-ui-lib/build.gradle.kts index a7feed4b..1838eb6b 100644 --- a/sdk-ext-ui-lib/build.gradle.kts +++ b/sdk-ext-ui-lib/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("secant.android-build-conventions") id("wtf.emulator.gradle") id("secant.emulator-wtf-conventions") + id("secant.jacoco-conventions") } android { diff --git a/settings.gradle.kts b/settings.gradle.kts index 844c09cd..f6b2946b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -292,6 +292,7 @@ dependencyResolutionManagement { "androidx-espresso-intents", "androidx-test-core", "androidx-test-junit", + "androidx-test-orchestrator", "androidx-test-runner" ) ) diff --git a/spackle-android-lib/build.gradle.kts b/spackle-android-lib/build.gradle.kts index d1077fe6..20e8e57d 100644 --- a/spackle-android-lib/build.gradle.kts +++ b/spackle-android-lib/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("secant.android-build-conventions") id("wtf.emulator.gradle") id("secant.emulator-wtf-conventions") + id("secant.jacoco-conventions") } android { diff --git a/test-lib/build.gradle.kts b/test-lib/build.gradle.kts index c50a067b..44513890 100644 --- a/test-lib/build.gradle.kts +++ b/test-lib/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") kotlin("android") id("secant.android-build-conventions") + id("secant.jacoco-conventions") } android { diff --git a/ui-design-lib/build.gradle.kts b/ui-design-lib/build.gradle.kts index d0f5a9e9..a91c3c1d 100644 --- a/ui-design-lib/build.gradle.kts +++ b/ui-design-lib/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") kotlin("android") id("secant.android-build-conventions") + id("secant.jacoco-conventions") } android { diff --git a/ui-integration-test/build.gradle.kts b/ui-integration-test/build.gradle.kts index 5a997630..c3fefff4 100644 --- a/ui-integration-test/build.gradle.kts +++ b/ui-integration-test/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("secant.android-build-conventions") id("wtf.emulator.gradle") id("secant.emulator-wtf-conventions") + id("secant.jacoco-conventions") } // Force orchestrator to be used for this module, because we need cleared state before each test diff --git a/ui-lib/build.gradle.kts b/ui-lib/build.gradle.kts index 5c509c6e..db2af153 100644 --- a/ui-lib/build.gradle.kts +++ b/ui-lib/build.gradle.kts @@ -4,6 +4,7 @@ plugins { id("secant.android-build-conventions") id("wtf.emulator.gradle") id("secant.emulator-wtf-conventions") + id("secant.jacoco-conventions") } android { @@ -93,6 +94,7 @@ dependencies { } if (project.property("IS_USE_TEST_ORCHESTRATOR").toString().toBoolean()) { + androidTestUtil(libs.androidx.test.services) androidTestUtil(libs.androidx.test.orchestrator) { artifact { type = "apk" @@ -100,3 +102,4 @@ dependencies { } } } + diff --git a/ui-screenshot-test/src/main/AndroidManifest.xml b/ui-screenshot-test/src/main/AndroidManifest.xml index 1c361547..8f5c90dd 100644 --- a/ui-screenshot-test/src/main/AndroidManifest.xml +++ b/ui-screenshot-test/src/main/AndroidManifest.xml @@ -3,6 +3,10 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> + + +