home / skills / hitoshura25 / claude-devtools / android-test-structure
This skill scaffolds androidTest directory structure with base test classes and utilities to accelerate Espresso-based Android UI testing.
npx playbooks add skill hitoshura25/claude-devtools --skill android-test-structureReview the files below or copy the command above to add this skill to your agents.
---
name: android-test-structure
description: Create androidTest directory structure with base classes and utilities
category: android
version: 1.0.0
inputs:
- project_path: Path to Android project
- package_name: App package name
outputs:
- app/src/androidTest/
- BaseTest.kt
- TestUtils.kt
verify: "test -d app/src/androidTest"
---
# Android Test Structure
Creates androidTest directory structure with base test class and utilities for Espresso testing.
## Prerequisites
- Android project with Gradle
- Espresso dependencies added (run `android-espresso-dependencies` first)
- Package name known
## Inputs
| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| project_path | Yes | . | Android project root |
| package_name | Yes | - | App package (e.g., com.example.app) |
## Process
### Step 1: Create Directory Structure
```bash
# Get package path from package name (com.example.app -> com/example/app)
PACKAGE_PATH=$(echo "${PACKAGE_NAME}" | tr '.' '/')
# Create androidTest directories
mkdir -p "app/src/androidTest/kotlin/${PACKAGE_PATH}/base"
mkdir -p "app/src/androidTest/kotlin/${PACKAGE_PATH}/utils"
mkdir -p "app/src/androidTest/kotlin/${PACKAGE_PATH}/screens"
```
### Step 2: Create BaseTest.kt
Create `app/src/androidTest/kotlin/${PACKAGE_PATH}/base/BaseTest.kt`:
```kotlin
package ${PACKAGE_NAME}.base
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.rules.ActivityScenarioRule
import org.junit.After
import org.junit.Before
import org.junit.Rule
/**
* Base class for all instrumented tests.
* Provides common setup, teardown, and utilities.
*/
abstract class BaseTest {
protected val context: Context = ApplicationProvider.getApplicationContext()
@Before
open fun setUp() {
// Common setup for all tests
// Override in subclasses for specific setup
}
@After
open fun tearDown() {
// Common cleanup
// Override in subclasses for specific cleanup
}
/**
* Wait for idle state before proceeding
*/
protected fun waitForIdle() {
androidx.test.espresso.Espresso.onIdle()
}
}
```
### Step 3: Create TestUtils.kt
Create `app/src/androidTest/kotlin/${PACKAGE_PATH}/utils/TestUtils.kt`:
```kotlin
package ${PACKAGE_NAME}.utils
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
import org.hamcrest.Matcher
object TestUtils {
/**
* Custom action to get RecyclerView item count
*/
fun getRecyclerViewItemCount(recyclerView: RecyclerView): Int {
return recyclerView.adapter?.itemCount ?: 0
}
/**
* Wait for a condition with timeout
*/
fun waitForCondition(
timeoutMs: Long = 5000,
condition: () -> Boolean
): Boolean {
val startTime = System.currentTimeMillis()
while (System.currentTimeMillis() - startTime < timeoutMs) {
if (condition()) return true
Thread.sleep(100)
}
return false
}
/**
* Custom ViewAction to perform click on specific position
*/
fun clickOnViewChild(viewId: Int): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View>? {
return null
}
override fun getDescription(): String {
return "Click on a child view with specified id."
}
override fun perform(uiController: UiController, view: View) {
val v = view.findViewById<View>(viewId)
v.performClick()
}
}
}
}
```
### Step 4: Create README for Tests
Create `app/src/androidTest/README.md`:
```markdown
# Android E2E Tests
This directory contains end-to-end UI tests using Espresso.
## Structure
- `base/` - Base classes for all tests
- `utils/` - Test utilities and helpers
- `screens/` - Screen-specific test classes
## Running Tests
```bash
# All tests
./gradlew connectedAndroidTest
# Specific test class
./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.app.screens.MainActivityTest
```
## Writing Tests
1. Extend `BaseTest` for common setup
2. Use utilities from `TestUtils`
3. Follow AAA pattern: Arrange, Act, Assert
```
## Verification
**MANDATORY:** Run these commands:
```bash
# Verify directory structure exists
test -d app/src/androidTest && echo "✓ androidTest directory created"
# Verify base classes exist
test -f app/src/androidTest/kotlin/*/base/BaseTest.kt && echo "✓ BaseTest.kt created"
# Verify utils exist
test -f app/src/androidTest/kotlin/*/utils/TestUtils.kt && echo "✓ TestUtils.kt created"
```
**Expected output:**
- ✓ androidTest directory created
- ✓ BaseTest.kt created
- ✓ TestUtils.kt created
## Outputs
| Output | Location | Description |
|--------|----------|-------------|
| Directory structure | app/src/androidTest/ | Test source directory |
| BaseTest class | base/BaseTest.kt | Common test setup |
| Test utilities | utils/TestUtils.kt | Helper functions |
| README | README.md | Test documentation |
## Troubleshooting
### "Package path incorrect"
**Cause:** Package name format wrong
**Fix:** Use format: com.example.app (not path format)
### "Directory already exists"
**Cause:** androidTest directory already created
**Fix:** Merge with existing structure, don't overwrite
## Completion Criteria
- [ ] `app/src/androidTest/` directory exists
- [ ] `base/BaseTest.kt` exists
- [ ] `utils/TestUtils.kt` exists
- [ ] `screens/` directory exists
- [ ] README.md created
This skill creates a ready-to-use androidTest directory structure with a base test class and common utilities tailored for Espresso instrumented tests. It scaffolds base/, utils/, and screens/ packages, adds BaseTest.kt and TestUtils.kt, and includes a test README to document usage and running instructions.
The script derives the Kotlin package path from the provided package name and creates the corresponding directories under app/src/androidTest/kotlin/. It writes a BaseTest.kt with common setup/teardown hooks and a TestUtils.kt that contains helper functions like RecyclerView item count, a wait-for-condition helper, and a custom ViewAction for child clicks. It also creates an androidTest README and includes verification commands to confirm files and directories exist.
What package_name format is required?
Use the standard Java package format with dots, for example com.example.app; do not pass a file path.
Will this overwrite existing test files?
The process creates directories and files; if files already exist, merge changes manually to avoid overwriting custom code.