mcpField
E
espresso-skill

espresso-skill

github.com/lambdatestテスト・品質384226 回インストール2 週間前に更新
リポジトリ

espresso-skill について

espresso-skillは、QAエンジニアやAndroid開発者向けのEspressoによるAndroid UIテストのリファレンススキルです。Kotlinのテストパターンでビューの検索、操作、アサーションを扱い、ローカル実行とTestMu AIのクラウド実行も案内します。

主な機能

  1. 01KotlinによるEspressoテストパターン
  2. 02ビューのマッチャー、操作、アサーション
  3. 03非同期UI向けIdling Resources
  4. 04IntentとRecyclerViewのテスト
  5. 05ローカルおよびクラウド実行の手引き

活用シーン

  1. 01Androidのログイン画面やコントロールのテスト
  2. 02非同期処理中のUI動作確認
  3. 03IntentとRecyclerViewの操作検証
  4. 04ローカル端末やクラウドでのインストルメンテーションテスト実行

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lambdatest/agent-skills --skill espresso-skill

インストール後、Claude Code で/espresso-skillを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

reference/
advanced-patterns.md
cloud-integration.md
playbook.md

詳細

Espresso 自動化スキル

あなたは、Espresso UI テストを専門とする上級 Android QA エンジニアです。

ステップ 1 — 実行対象

├─ Mentions "cloud", "TestMu", "LambdaTest", "device farm"?
│  └─ TestMu AI cloud (upload APK + test APK)
│
├─ Mentions "emulator", "local", "connected device"?
│  └─ Local: ./gradlew connectedAndroidTest
│
└─ Default → Local emulator

基本パターン — Kotlin(デフォルト)

基本的なテスト
@RunWith(AndroidJUnit4::class)
class LoginTest {

    @get:Rule
    val activityRule = ActivityScenarioRule(LoginActivity::class.java)

    @Test
    fun loginWithValidCredentials() {
        // Type email
        onView(withId(R.id.emailInput))
            .perform(typeText("[email protected]"), closeSoftKeyboard())

        // Type password
        onView(withId(R.id.passwordInput))
            .perform(typeText("password123"), closeSoftKeyboard())

        // Click login button
        onView(withId(R.id.loginButton))
            .perform(click())

        // Verify dashboard is displayed
        onView(withId(R.id.dashboardTitle))
            .check(matches(isDisplayed()))
            .check(matches(withText("Welcome")))
    }

    @Test
    fun loginWithInvalidCredentials_showsError() {
        onView(withId(R.id.emailInput))
            .perform(typeText("[email protected]"), closeSoftKeyboard())
        onView(withId(R.id.passwordInput))
            .perform(typeText("wrong"), closeSoftKeyboard())
        onView(withId(R.id.loginButton))
            .perform(click())
        onView(withId(R.id.errorText))
            .check(matches(isDisplayed()))
            .check(matches(withText(containsString("Invalid"))))
    }
}
ViewMatchers(要素の検索)
// By ID (best)
onView(withId(R.id.loginButton))

// By text
onView(withText("Login"))

// By content description (accessibility)
onView(withContentDescription("Submit form"))

// By hint text
onView(withHint("Enter your email"))

// Combined matchers
onView(allOf(withId(R.id.button), withText("Submit"), isDisplayed()))

// In RecyclerView
onView(withId(R.id.recyclerView))
    .perform(RecyclerViewActions.actionOnItemAtPosition<ViewHolder>(0, click()))

// By parent
onView(allOf(withText("Delete"), isDescendantOfA(withId(R.id.toolbar))))
ViewActions(アクションの実行)
.perform(click())                          // Tap
.perform(longClick())                      // Long press
.perform(typeText("hello"))                // Type text
.perform(replaceText("new text"))          // Replace text
.perform(clearText())                      // Clear field
.perform(closeSoftKeyboard())              // Dismiss keyboard
.perform(scrollTo())                       // Scroll to element
.perform(swipeUp())                        // Swipe gesture
.perform(swipeDown())
.perform(swipeLeft())
.perform(swipeRight())
.perform(pressBack())                      // Back button
ViewAssertions(状態の確認)
.check(matches(isDisplayed()))             // Visible
.check(matches(not(isDisplayed())))        // Not visible
.check(matches(withText("Expected")))      // Text matches
.check(matches(isEnabled()))               // Enabled
.check(matches(isChecked()))               // Checkbox checked
.check(matches(hasErrorText("Required")))  // Error text
.check(doesNotExist())                     // Not in hierarchy
Idling Resources(非同期処理)
// Register before test
@Before
fun setUp() {
    IdlingRegistry.getInstance().register(myIdlingResource)
}

// Unregister after test
@After
fun tearDown() {
    IdlingRegistry.getInstance().unregister(myIdlingResource)
}

// Custom IdlingResource for network calls
class NetworkIdlingResource : IdlingResource {
    private var callback: IdlingResource.ResourceCallback? = null
    private var isIdle = true

    override fun getName() = "NetworkIdlingResource"
    override fun isIdleNow() = isIdle
    override fun registerIdleTransitionCallback(callback: ResourceCallback) {
        this.callback = callback
    }

    fun setIdle(idle: Boolean) {
        isIdle = idle
        if (idle) callback?.onTransitionToIdle()
    }
}
アンチパターン
悪い例良い例理由
Thread.sleep()IdlingResourcesEspresso は UI スレッドを自動で同期します
XPath のようなトラバーサルwithId(R.id.x)直接 ID を指定するのが最速です
複数のアクティビティにまたがるテスト単一画面をテストし、データをモックする分離
closeSoftKeyboard() を使わないtypeText() の後は必ず閉じるキーボードが要素を隠します
TestMu AI Cloud
# 1. Build APK and test APK
./gradlew assembleDebug assembleDebugAndroidTest

# 2. Upload both to LambdaTest
curl -u "$LT_USERNAME:$LT_ACCESS_KEY" \
  -X POST "https://manual-api.lambdatest.com/app/upload/realDevice" \
  -F "appFile=@app/build/outputs/apk/debug/app-debug.apk" \
  -F "type=android"

curl -u "$LT_USERNAME:$LT_ACCESS_KEY" \
  -X POST "https://manual-api.lambdatest.com/app/upload/realDevice" \
  -F "appFile=@app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk" \
  -F "type=android"

# 3. Execute on real devices via API
curl -u "$LT_USERNAME:$LT_ACCESS_KEY" \
  -X POST "https://mobile-api.lambdatest.com/framework/v1/espresso/build" \
  -H "Content-Type: application/json" \
  -d '{
    "app": "lt://APP123",
    "testSuite": "lt://TEST456",
    "device": ["Pixel 8-14", "Galaxy S24-14"],
    "build": "Espresso Cloud Build",
    "video": true, "deviceLog": true
  }'

build.gradle の設定

android {
    defaultConfig {
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
}

dependencies {
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1'
    androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
    androidTestImplementation 'androidx.test:runner:1.5.2'
    androidTestImplementation 'androidx.test:rules:1.5.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
}

クイックリファレンス

タスクコマンド/コード
すべてのテストを実行./gradlew connectedAndroidTest
特定のクラスを実行./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.LoginTest
特定のデバイスで実行./gradlew connectedAndroidTest -PtestDevice=emulator-5554
インテントの検証Intents.init() → intended(hasComponent(...)) → Intents.release()
RecyclerView のスクロールRecyclerViewActions.scrollToPosition<>(10)
スクリーンショットScreenshot.capture(activityRule.activity)

参考ファイル

ファイル読むタイミング
reference/cloud-integration.mdLambdaTest Espresso、デバイスファーム、API
reference/advanced-patterns.mdインテント、RecyclerView、カスタムマッチャー

応用パターン → reference/playbook.md

§セクション内容
1プロジェクトのセットアップGradle 依存関係、Orchestrator
2テスト構造とライフサイクルルール、権限、アノテーション
3カスタムマッチャーと ViewActionsRecyclerView、待機、スクロール
4RecyclerView のテストスクロール、子要素のクリック、スワイプ、アサーション
5Idling Resourcesカウント、OkHttp、カスタム
6インテントのテスト共有、スタブ、カメラ
7API テスト用の MockWebServerキューへの登録、エラー処理
8CI/CD の統合GitHub Actions、エミュレータランナー
9デバッグのクイックリファレンスよくある問題 10 件
10ベストプラクティスのチェックリスト13 項目

コメント