test infra: JUnit5 unit tests on Android modules + Compose UI test wiring

Add an architecture.android.unit.test convention plugin that runs local unit
tests on the JUnit5 platform via useJUnitPlatform() (AndroidUnitTest extends
Gradle's Test) + the unit-test bundle. Deliberately NOT using the
de.mannodermaus plugin (targets AGP 8.x; we're on AGP 9). Add
junit-platform-launcher (Gradle 9 dropped the bundled launcher); set the
instrumentation runner; add a compose-ui-test bundle pinning espresso/runner to
current versions (transitive espresso 3.5.0 calls the removed
InputManager.getInstance() on API 34+). CI now runs ./gradlew test and compiles
the instrumented tests. Drop unused testing catalog entries.
This commit is contained in:
2026-06-10 15:00:37 +02:00
parent cf63095acc
commit 7a7ab45a66
9 changed files with 82 additions and 11 deletions

View File

@@ -47,6 +47,10 @@ gradlePlugin {
id = "architecture.domain.module"
implementationClass = "com.example.architecture.convention.DomainModuleConventionPlugin"
}
register("androidUnitTest") {
id = "architecture.android.unit.test"
implementationClass = "com.example.architecture.convention.AndroidUnitTestConventionPlugin"
}
register("compose") {
id = "architecture.compose"
implementationClass = "com.example.architecture.convention.ComposeConventionPlugin"

View File

@@ -19,6 +19,9 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
defaultConfig {
minSdk = MIN_SDK
// Used by instrumented (androidTest) tests, e.g. the Compose UI test in
// :feature:characters:presentation-compose. Harmless for modules without androidTest.
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {

View File

@@ -0,0 +1,32 @@
package com.example.architecture.convention
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.withType
/**
* Runs an Android library module's local unit tests (`src/test`) on the **JUnit 5 platform** with the
* shared `unit-test` toolset (JUnit Jupiter, kotlinx-coroutines-test, Turbine, AssertK).
*
* Deliberately does NOT use the `de.mannodermaus.android-junit5` Gradle plugin: its 1.11.x line
* targets AGP 8.x and we build on AGP 9.0. It isn't needed for *local* unit tests anyway —
* `com.android.build.gradle.tasks.factory.AndroidUnitTest` extends Gradle's [Test] task, so calling
* `useJUnitPlatform()` on it is enough (this mirrors `DomainModuleConventionPlugin`, which does the
* same for pure-JVM modules).
*/
class AndroidUnitTestConventionPlugin : Plugin<Project> {
override fun apply(target: Project) = with(target) {
dependencies {
add("testImplementation", libs.findBundle("unit-test").get())
add("testRuntimeOnly", libs.findLibrary("junit-jupiter-engine").get())
// Gradle 9 dropped the bundled launcher; JUnit 5 won't start without it.
add("testRuntimeOnly", libs.findLibrary("junit-platform-launcher").get())
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
}
}

View File

@@ -21,6 +21,8 @@ class DomainModuleConventionPlugin : Plugin<Project> {
add("testImplementation", libs.findLibrary("junit-jupiter-api").get())
add("testImplementation", libs.findLibrary("assertk").get())
add("testRuntimeOnly", libs.findLibrary("junit-jupiter-engine").get())
// Gradle 9 dropped the bundled launcher; JUnit 5 won't start without it.
add("testRuntimeOnly", libs.findLibrary("junit-platform-launcher").get())
}
tasks.withType<Test>().configureEach {