android-test-structure

Create androidTest directory structure with base classes and utilities

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "android-test-structure" with this command: npx skills add hitoshura25/claude-devtools/hitoshura25-claude-devtools-android-test-structure

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

InputRequiredDefaultDescription
project_pathYes.Android project root
package_nameYes-App package (e.g., com.example.app)

Process

Step 1: Create Directory Structure

# 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:

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:

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:

# 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

OutputLocationDescription
Directory structureapp/src/androidTest/Test source directory
BaseTest classbase/BaseTest.ktCommon test setup
Test utilitiesutils/TestUtils.ktHelper functions
READMEREADME.mdTest 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

android-playstore-setup

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

android-proguard-setup

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

android-playstore-scan

No summary provided by upstream source.

Repository SourceNeeds Review