ci: Instrumentation tests coverage in ci.
All checks were successful
Check PR code / BuildAndTestAndCoverage (pull_request) Successful in 34m46s

This commit is contained in:
2025-03-16 15:55:10 +01:00
parent 02d503e03a
commit 7c65a63315
14 changed files with 583 additions and 151 deletions

View File

@@ -10,6 +10,7 @@ plugins {
id("com.mikepenz.aboutlibraries.plugin")
id("org.jetbrains.kotlinx.kover")
id("app.cash.sqldelight") version "2.0.2"
jacoco
}
fun Project.execWithOutput(
@@ -64,6 +65,15 @@ fun versionNameFromGit(): String {
return gitVersion()
}
val exclusions =
listOf(
"**/R.class",
"**/R\$*.class",
"**/BuildConfig.*",
"**/Manifest*.*",
"**/*Test*.*",
)
android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
@@ -95,7 +105,7 @@ android {
// tests
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["clearPackageData"] = "true"
testInstrumentationRunnerArguments["useTestStorageService"] = "true"
}
packaging {
resources {
@@ -109,6 +119,44 @@ android {
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
getByName("debug") {
isTestCoverageEnabled = true
enableAndroidTestCoverage = true
installation {
installOptions("-g", "-r")
}
val androidTests = "connectedAndroidTest"
tasks.register<JacocoReport>("JacocoDebugCodeCoverage") {
// Depend on unit tests and Android tests tasks
dependsOn(listOf(androidTests))
// Set task grouping and description
group = "Reporting"
description = "Execute UI and unit tests, generate and combine Jacoco coverage report"
// Configure reports to generate both XML and HTML formats
reports {
xml.required.set(true)
html.required.set(true)
}
// Set source directories to the main source directory
sourceDirectories.setFrom(layout.projectDirectory.dir("src/main"))
// Set class directories to compiled Java and Kotlin classes, excluding specified exclusions
classDirectories.setFrom(
files(
fileTree(layout.buildDirectory.dir("intermediates/javac/")) {
exclude(exclusions)
},
fileTree(layout.buildDirectory.dir("tmp/kotlin-classes/")) {
exclude(exclusions)
},
),
)
// Collect execution data from .exec and .ec files generated during test execution
executionData.setFrom(
files(
fileTree(layout.buildDirectory) { include(listOf("**/*.exec", "**/*.ec")) },
),
)
}
}
}
flavorDimensions.add("build")
@@ -121,7 +169,6 @@ android {
namespace = "bou.amine.apps.readerforselfossv2.android"
testOptions {
animationsDisabled = true
execution = "ANDROIDX_TEST_ORCHESTRATOR"
unitTests {
isIncludeAndroidResources = true
}
@@ -154,8 +201,8 @@ dependencies {
implementation("androidx.multidex:multidex:2.0.1")
// About
implementation("com.mikepenz:aboutlibraries-core:10.5.1")
implementation("com.mikepenz:aboutlibraries:10.5.1")
implementation("com.mikepenz:aboutlibraries-core:11.6.3")
implementation("com.mikepenz:aboutlibraries:11.6.3")
// Material-ish things
implementation("com.ashokvarma.android:bottom-navigation-bar:2.2.0")
@@ -197,14 +244,15 @@ dependencies {
testImplementation("io.mockk:mockk:1.13.14")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1")
androidTestImplementation("androidx.test:runner:1.6.2")
androidTestImplementation("androidx.test:rules:1.6.1")
androidTestImplementation("androidx.test:runner:1.7.0-alpha01")
androidTestImplementation("androidx.test:rules:1.7.0-alpha01")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
implementation("androidx.test.espresso:espresso-idling-resource:3.6.1")
androidTestImplementation("androidx.test.ext:junit-ktx:1.2.1")
androidTestUtil("androidx.test:orchestrator:1.5.1")
androidTestUtil("androidx.test.services:test-services:1.6.0-alpha02")
testImplementation("org.robolectric:robolectric:4.14.1")
testImplementation("androidx.test:core-ktx:1.6.1")
testImplementation("androidx.test:core-ktx:1.7.0-alpha01")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
implementation("ch.acra:acra-http:$acraVersion")
implementation("ch.acra:acra-toast:$acraVersion")
@@ -224,9 +272,16 @@ tasks.withType<Test> {
)
showStandardStreams = true
}
if (this.name == "connectedAndroidTest") {
configure<JacocoTaskExtension> {
isIncludeNoLocationClasses = true
excludes = listOf("jdk.internal.*")
}
}
}
aboutLibraries {
excludeFields = arrayOf("generated")
offlineMode = true
fetchRemoteLicense = false
fetchRemoteFunding = false
@@ -235,3 +290,30 @@ aboutLibraries {
duplicationMode = com.mikepenz.aboutlibraries.plugin.DuplicateMode.MERGE
duplicationRule = com.mikepenz.aboutlibraries.plugin.DuplicateRule.GROUP
}
val clearScreenshotsTask =
tasks.register<Exec>("clearScreenshots") {
println("AMINE : clear")
commandLine = listOf("adb", "shell", "rm", "-r", "/storage/emulated/0/Pictures/selfoss_tests/screenshots/*")
}
val createScreenshotDirectoryTask =
tasks.register<Exec>("createScreenshotDirectory") {
println("AMINE : create directory")
group = "reporting"
commandLine = listOf("adb", "shell", "mkdir", "-p", "/storage/emulated/0/Pictures/selfoss_tests/screenshots")
}
tasks.register<Exec>("fetchScreenshots") {
val reportsDirectory = file("$buildDir/reports/androidTests/connected")
println("AMINE : fetch")
group = "reporting"
executable(android.adbExecutable.toString())
commandLine = listOf("adb", "pull", "/storage/emulated/0/Pictures/selfoss_tests/screenshots", reportsDirectory.toString())
finalizedBy(clearScreenshotsTask)
doFirst {
reportsDirectory.mkdirs()
}
}