Claude Code Plugins

Community-maintained marketplace

Feedback

android-test-structure

@hitoshura25/claude-devtools
0
0

Create androidTest directory structure with base classes and utilities

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name android-test-structure
description Create androidTest directory structure with base classes and utilities
category android
version 1.0.0
inputs [object Object], [object Object]
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

# 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

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