Configuring Test Dependencies
Communityskydoves
Use this skill to wire the correct Gradle dependency matrix for Jetpack Compose UI tests. Covers `androidTestImplementation("androidx.compose.ui:ui-test-junit4")`, the `debugImplementation("androidx.compose.ui:ui-test-manifest")` requirement that makes `createComposeRule()` work, the host-test (Robolectric) trio, the accessibility add-ons (`ui-test-accessibility`, `ui-test-junit4-accessibility`), and the `TestManifestGradleConfiguration` lint warning. Use when the user reports `ActivityNotFoundException: ComponentActivity`, `createComposeRule unresolved`, `lint warning ui-test-manifest`, `Cannot find test rule`, or asks "what dependencies do I need for Compose UI tests" / "why won't my Compose test compile".
Overview
- Repository
- skydoves/android-testing-skills
- Publisher
- skydoves
- Stars
- 347
- Forks
- 14
- Bundled files
- 0
- License
- Apache-2.0
- Updated
- May 25, 2026
Installation
tmp=$(mktemp -d)
git clone --depth 1 https://github.com/skydoves/android-testing-skills.git "$tmp"
mkdir -p ~/.claude/skills
cp -R "$tmp/compose/setup/configuring-test-dependencies" ~/.claude/skills/configuring-test-dependencies
rm -rf "$tmp"tmp=$(mktemp -d)
git clone --depth 1 https://github.com/skydoves/android-testing-skills.git "$tmp"
mkdir -p ~/.codex/skills
cp -R "$tmp/compose/setup/configuring-test-dependencies" ~/.codex/skills/configuring-test-dependencies
rm -rf "$tmp"Install the Configuring Test Dependencies agent skill from https://github.com/skydoves/android-testing-skills/tree/main/compose/setup/configuring-test-dependencies into this project's skills folder.Instructions
Configuring Test Dependencies — Get the Gradle Matrix Right
Compose UI tests fail at the dependency layer in three predictable ways: the JUnit4 surface is on the wrong source set, the ui-test-manifest artifact is missing or on the wrong configuration, or the host-test trio is incomplete. This skill encodes the exact matrix and the lint warning that polices it. Subsequent skills (choosing-test-rule-vs-runtest/SKILL.md, setting-up-host-vs-device-tests/SKILL.md) assume the dependencies are correct.
When to use this skill
- The user reports
java.lang.RuntimeException: Could not launch activity within 45 seconds. Examined activities: ... androidx.activity.ComponentActivityorActivityNotFoundException. - The IDE flags
createComposeRuleas unresolved orimport androidx.compose.ui.test.junit4.createComposeRuleas red. - Lint surfaces
TestManifestGradleConfiguration(severity WARNING) on abuild.gradle.ktsline. - The user wants to add Robolectric / host (JVM) tests for Compose and asks which artifacts to depend on.
- The user wants to opt into
enableAccessibilityChecks(...)and is unsure which artifact owns it.
When NOT to use this skill
- Dependencies are already correct and the user is choosing between
createComposeRule()andrunComposeUiTest { }— use./choosing-test-rule-vs-runtest/SKILL.md. - Dependencies compile but the test runs in the wrong source set (
test/vsandroidTest/) — use./setting-up-host-vs-device-tests/SKILL.md. - The test compiles and runs but is flaky/timing-out — start with
../../synchronization/synchronizing-with-idle/SKILL.md.
Prerequisites
- Android Gradle Plugin with the
com.android.applicationorcom.android.libraryplugin applied. - A Compose-enabled module (the
org.jetbrains.kotlin.plugin.composeplugin orbuildFeatures.compose = true). - A JUnit4 dependency on the test classpath (Compose's
ui-test-junit4artifact still uses JUnit4; JUnit5 requires a third-party Vintage engine bridge and is out of scope).
Workflow
1. Decide which test surfaces the module needs. A typical Compose feature module wants three: instrumentation tests for screenshot/RenderThread/full-stack coverage, host (Robolectric) tests for fast logic checks, and the manifest helper for
createComposeRule(). Pick from the matrix in step 2.2. Add dependencies on the correct configurations. Copy this into the module's
build.gradle.kts:
dependencies {
// --- Instrumentation tests (src/androidTest/) ---
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
// MUST be debugImplementation (see Pattern: WRONG vs RIGHT for ui-test-manifest below)
debugImplementation("androidx.compose.ui:ui-test-manifest")
// --- Host tests with Robolectric (src/test/) ---
testImplementation("androidx.compose.ui:ui-test") // common test API
testImplementation("androidx.compose.ui:ui-test-junit4") // ComposeTestRule + createComposeRule
testImplementation("androidx.compose.ui:ui-test-manifest") // ComponentActivity manifest entry
testImplementation("org.robolectric:robolectric:4.13") // pin a version
// --- Optional: accessibility validation (API 34+) ---
androidTestImplementation("androidx.compose.ui:ui-test-junit4-accessibility")
// Or, when using runComposeUiTest { } (no Rule):
androidTestImplementation("androidx.compose.ui:ui-test-accessibility")
}The exact GA versions come from the Compose UI BOM or the developer's chosen composeVersion. Pin Robolectric independently — it does not ship in the Compose BOM.
- 3. If the test fails with
ActivityNotFoundExceptionforandroidx.activity.ComponentActivity, the manifest artifact is the cause 99 percent of the time. That artifact is a single-file library that merges this<activity>entry into the test APK manifest, taken fromcompose/ui/ui-test-manifest/src/main/AndroidManifest.xml:
<activity android:theme="@android:style/Theme.Material.Light.NoActionBar"
android:name="androidx.activity.ComponentActivity" android:exported="true" />Without that entry, createComposeRule() and runComposeUiTest { } (which both default to launching androidx.activity.ComponentActivity via ActivityScenario.launch) crash at launch time. Diagnosis:
Confirm
ui-test-manifestis in the dependency list at all.Confirm it is on
debugImplementation(ortestImplementationfor host tests). If it is onandroidTestImplementation, lint flags it and Gradle still wires it in — but the AGP variant model intentionally separatesdebugandandroidTestmanifest merging, and putting it onandroidTestImplementationdoes NOT merge the<activity>into the host APK that the instrumentation runs against. The lint check exists precisely to catch this.4. Address the
TestManifestGradleConfigurationlint warning by moving the dependency todebugImplementation. The lint check lives incompose/ui/ui-test-manifest-lint/src/main/java/androidx/compose/ui/test/manifest/lint/GradleDebugConfigurationDetector.kt. Severity isSeverity.WARNINGand the quick fix replaces the configuration name withdebugImplementation. The check fires when the artifact appears onimplementation,api,compileOnly,runtimeOnly,androidTestImplementation,testImplementation, or any custom configuration whose name starts withandroid/test/ one of the supported config names.5. Decide whether the manifest artifact is needed at all. It is required when:
- The test uses
createComposeRule()(no type parameter — defaults toandroidx.activity.ComponentActivity). - The test uses
runComposeUiTest { }(no type parameter — same default).
It is NOT required when:
- The test uses
createAndroidComposeRule<MyActivity>()AND the developer declares<activity android:name=".MyActivity" .../>themselves insrc/androidTest/AndroidManifest.xml(orsrc/debug/AndroidManifest.xml). - The test uses
createEmptyComposeRule()and launches its ownActivityScenarioagainst an Activity already declared in the production manifest.
- The test uses
6. For host tests, ensure all three artifacts are on
testImplementation. Robolectric drives the JVM Looper, but Compose's idling/clock implementations requireui-test(common) plusui-test-junit4(ComposeTestRuleinterface andcreateComposeRuleactual). Withoutui-test-manifestontestImplementation, Robolectric throws the sameActivityNotFoundExceptionbecause it parses the same manifest. The host source set in androidx itself uses this configuration — seecompose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/RobolectricComposeTest.kt.7. Add accessibility artifacts only if the developer plans to call
enableAccessibilityChecks. They are independent of the JUnit4 surface:ui-test-accessibilityextendsComposeUiTest(the receiver ofrunComposeUiTest { }).ui-test-junit4-accessibilityextendsComposeTestRule/AndroidComposeTestRule. Both are@RequiresApi(34), both are no-op on Robolectric (Build.FINGERPRINT == "robolectric"triggers a logged warning) — see the accessibility skill in this repo for follow-up.
8. Sync Gradle and re-run the test. A clean
./gradlew :app:connectedDebugAndroidTest(instrumentation) or./gradlew :app:testDebugUnitTest(host) should compile and locateComponentActivity.
Patterns
Pattern: WRONG vs RIGHT — ui-test-manifest configuration
// WRONG
dependencies {
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
androidTestImplementation("androidx.compose.ui:ui-test-manifest")
}
// WRONG because: lint emits TestManifestGradleConfiguration (WARNING) and the manifest
// merger does not pull the <activity> entry into the merged APK manifest from the
// androidTest source set. createComposeRule() crashes with ActivityNotFoundException.// RIGHT
dependencies {
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}The lint check explicitly allows debugImplementation and warns on every other configuration. From GradleDebugConfigurationDetector.kt:
"The androidx.compose.ui:ui-test-manifest dependency is needed for launching a
Compose host, such as with createComposeRule. However, it only needs to be present
in testing configurations therefore use this dependency with the debugImplementation
configuration"
Pattern: WRONG vs RIGHT — host-test dependencies
// WRONG
dependencies {
testImplementation("androidx.compose.ui:ui-test-junit4")
testImplementation("org.robolectric:robolectric:4.13")
// Missing ui-test-manifest -> ActivityNotFoundException at runComposeUiTest launch
// Missing ui-test -> linker errors on common test API symbols
}// RIGHT
dependencies {
testImplementation("androidx.compose.ui:ui-test")
testImplementation("androidx.compose.ui:ui-test-junit4")
testImplementation("androidx.compose.ui:ui-test-manifest")
testImplementation("org.robolectric:robolectric:4.13")
}Pattern: WRONG vs RIGHT — custom Activity without its own manifest entry
// WRONG
@get:Rule val rule = createAndroidComposeRule<MyHostActivity>()
// build.gradle.kts has only debugImplementation("androidx.compose.ui:ui-test-manifest")
// and src/androidTest/AndroidManifest.xml does NOT declare MyHostActivity.
// WRONG because: ui-test-manifest only declares ComponentActivity. Custom activities
// must be declared in the test APK manifest by the developer. Result: ActivityNotFoundException.<!-- RIGHT — src/androidTest/AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name=".MyHostActivity" android:exported="true" />
</application>
</manifest>Pattern: complete sample build.gradle.kts
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.compose")
}
android {
namespace = "com.example.feature"
compileSdk = 35
defaultConfig {
minSdk = 23
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures { compose = true }
testOptions {
unitTests.isIncludeAndroidResources = true // required for Robolectric + Compose
}
}
dependencies {
val composeBom = platform("androidx.compose:compose-bom:2025.06.00")
implementation(composeBom)
androidTestImplementation(composeBom)
testImplementation(composeBom)
// Production
implementation("androidx.compose.ui:ui")
implementation("androidx.activity:activity-compose")
// Instrumentation
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-test-manifest")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
// Host (Robolectric)
testImplementation("androidx.compose.ui:ui-test")
testImplementation("androidx.compose.ui:ui-test-junit4")
testImplementation("androidx.compose.ui:ui-test-manifest")
testImplementation("org.robolectric:robolectric:4.13")
testImplementation("junit:junit:4.13.2")
}testOptions.unitTests.isIncludeAndroidResources = true is required so Robolectric can read merged resources during host tests of Compose content.
Mandatory rules
- MUST put
androidx.compose.ui:ui-test-manifestondebugImplementationfor instrumentation tests, and ontestImplementationfor host tests. Never onandroidTestImplementation,implementation, orapi. - MUST keep
ui-test-junit4on the same source set as the test that importscreateComposeRule/ComposeTestRule. MixingandroidTestImplementation(instrumentation) andtestImplementation(host) in the same module is fine; mixing them on the wrong test class is a compile error. - MUST declare any non-
ComponentActivitytest host (custom Activity) in the test APK manifest atsrc/androidTest/AndroidManifest.xmlorsrc/debug/AndroidManifest.xml. Theui-test-manifestartifact only declaresandroidx.activity.ComponentActivity. - MUST NOT remove the
TestManifestGradleConfigurationlint check vialintOptions { disable("TestManifestGradleConfiguration") }. Apply the quick fix instead — the check exists to prevent silent test failures. - MUST NOT put
ui-test-manifeston a release configuration (releaseImplementation,implementation). The artifact is purely a test scaffold and bloats production APKs with an unwanted<activity>entry. - PREFERRED: rely on the Compose BOM (
androidx.compose:compose-bom) so allui-test-*artifacts share a coherent version. Robolectric is independent and pins separately. - PREFERRED: when in doubt about which artifact owns a symbol, search
androidx/compose/ui/ui-test*paths from the corpus rather than guessing — see References.
Verification
-
./gradlew :<module>:connectedDebugAndroidTestcompiles and runs withoutActivityNotFoundExceptionforandroidx.activity.ComponentActivity. -
./gradlew :<module>:lintdoes NOT reportTestManifestGradleConfiguration. -
./gradlew :<module>:testDebugUnitTestcompiles when host tests userunComposeUiTest { }orcreateComposeRule(). - The dependency block visibly separates
androidTestImplementation(instrumentation),debugImplementation(manifest),testImplementation(host trio). - If the developer added accessibility artifacts,
enableAccessibilityChecks(...)resolves at compile time inside an instrumentation test. - The test APK manifest contains exactly one
<activity android:name="androidx.activity.ComponentActivity"/>entry (run./gradlew :app:processDebugAndroidTestManifestand inspectbuild/intermediates/.../AndroidManifest.xml).
References
- Compose testing setup (Android Developers): https://developer.android.com/develop/ui/compose/testing#setup
- Compose testing overview: https://developer.android.com/develop/ui/compose/testing
- Compose UI release notes: https://developer.android.com/jetpack/androidx/releases/compose-ui
- Compose Multiplatform testing: https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-test.html
compose/ui/ui-test-manifest-lint/src/main/java/androidx/compose/ui/test/manifest/lint/GradleDebugConfigurationDetector.kt—TestManifestGradleConfigurationissue definition (severity WARNING, quick-fix todebugImplementation).compose/ui/ui-test-manifest/src/main/AndroidManifest.xml— the merged<activity android:name="androidx.activity.ComponentActivity">entry thatcreateComposeRule()depends on.compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/ComposeUiTest.android.kt—runComposeUiTestlaunchesComponentActivity::class.javaby default (lines 184-197).compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/RobolectricComposeTest.kt— canonical host-test class skeleton with Robolectric (@RunWith(AndroidJUnit4::class) @Config(minSdk = RobolectricMinSdk)).compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/Constants.kt—internal const val RobolectricMinSdk = 23.
FAQ
What does Configuring Test Dependencies do?
Use this skill to wire the correct Gradle dependency matrix for Jetpack Compose UI tests. Covers `androidTestImplementation("androidx.compose.ui:ui-test-junit4")`, the `debugImplementation("androidx.compose.ui:ui-test-manifest")` requirement that makes `createComposeRule()` work, the host-test (Robolectric) trio, the accessibility add-ons (`ui-test-accessibility`, `ui-test-junit4-accessibility`), and the `TestManifestGradleConfiguration` lint warning. Use when the user reports `ActivityNotFoundException: ComponentActivity`, `createComposeRule unresolved`, `lint warning ui-test-manifest`, `Cannot find test rule`, or asks "what dependencies do I need for Compose UI tests" / "why won't my Compose test compile".
Who made Configuring Test Dependencies?
skydoves (a community member) publishes it in the skydoves/android-testing-skills repository on GitHub.
Is Configuring Test Dependencies free?
Yes. Configuring Test Dependencies is open source, published by skydoves under the Apache-2.0 license.
What comes with Configuring Test Dependencies?
Just its instructions. Everything the agent needs is in one SKILL.md file.
Which agents can use Configuring Test Dependencies?
Any coding agent that reads SKILL.md files, including Claude Code, Codex, Cursor, GitHub Copilot and Gemini CLI. The agent loads the skill when a task matches its description.
What are agent skills?
An agent skill is a folder with a SKILL.md file: instructions that teach a coding agent how to do one kind of task, and optionally files it can read while it works. The agent keeps only the skill's name and description in mind and reads the rest when a task calls for it.
How are agent skills different from MCP servers?
An MCP server gives an agent new tools to call, code that runs somewhere and returns results. A skill gives it knowledge: how to approach a task with the tools it already has. Many agents use both.
How can my agent test my Android app?
Robomori lets coding agents create, start and control Android emulators and devices from one command, so they can install your app, take screenshots and check dark mode, font sizes and languages.