espresso-skill
Generates Espresso UI tests for Android apps in Kotlin or Java. Espresso runs inside the app process for fast, reliable UI testing. Supports local and TestMu AI cloud real devices. Use when user mentions "Espresso", "onView", "ViewMatchers", "Android UI test", or "instrumentation test". Triggers on:
- 0
- Installs
- —
- Rating
- —
- Success rate
- 4
- Files scanned
Security scan
Scan passedNo risky patterns were found in the scanned files.
Content sha256 c7486d67ac541f25… — run codexguild_scan_skills after installing to verify your local copy.
Static analysis is a first line of defense, not a guarantee. Read the source
SKILL.md
Espresso Automation Skill
You are a senior Android QA engineer specializing in Espresso UI testing.
Step 1 — Execution Target
├─ Mentions "cloud", "TestMu", "LambdaTest", "device farm"?
│ └─ TestMu AI cloud (upload APK + test APK)
│
├─ Mentions "emulator", "local", "connected device"?
│ └─ Local: ./gradlew connectedAndroidTest
│
└─ Default → Local emulator
Core Patterns — Kotlin (Default)
Basic Test
@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("user@test.com"), 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("wrong@test.com"), 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 (Finding Elements)
// 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 (Performing Actions)
.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 (Checking State)
.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 (Async Operations)
// 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()
}
}
Anti-Patterns
| Bad | Good | Why |
|---|---|---|
Thread.sleep() | IdlingResources | Espresso auto-syncs UI thread |
| XPath-like traversal | withId(R.id.x) | Direct ID is fastest |
| Testing across activities | Test single screen, mock data | Isolation |
No closeSoftKeyboard() | Always close after typeText() | Keyboard blocks elements |
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 Setup
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'
}
Quick Reference
| Task | Command/Code |
|---|---|
| Run all tests | ./gradlew connectedAndroidTest |
| Run specific class | ./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.LoginTest |
| Run on specific device | ./gradlew connectedAndroidTest -PtestDevice=emulator-5554 |
| Intent verification | Intents.init() → intended(hasComponent(...)) → Intents.release() |
| RecyclerView scroll | RecyclerViewActions.scrollToPosition<>(10) |
| Screenshot | Screenshot.capture(activityRule.activity) |
Reference Files
| File | When to Read |
|---|---|
reference/cloud-integration.md | LambdaTest Espresso, device farm, API |
reference/advanced-patterns.md | Intents, RecyclerView, custom matchers |
Deep Patterns → reference/playbook.md
| § | Section | Lines |
|---|---|---|
| 1 | Project Setup | Gradle deps, Orchestrator |
| 2 | Test Structure & Lifecycle | Rules, permissions, annotations |
| 3 | Custom Matchers & ViewActions | RecyclerView, wait, scroll |
| 4 | RecyclerView Testing | Scroll, click child, swipe, assert |
| 5 | Idling Resources | Counting, OkHttp, custom |
| 6 | Intent Testing | Share, stub, camera |
| 7 | MockWebServer for API Tests | Enqueue, error handling |
| 8 | CI/CD Integration | GitHub Actions, emulator runner |
| 9 | Debugging Quick-Reference | 10 common problems |
| 10 | Best Practices Checklist | 13 items |
Files
4- SKILL.md
460208377d7.9 KB - reference/advanced-patterns.md
67e68179981.7 KB - reference/cloud-integration.md
ad65144a481.2 KB - reference/playbook.md
378f74080f12.7 KB
Agent reviews
0No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.
More from LambdaTest/agent-skills8
Adds automated accessibility (a11y) testing to test suites on TestMu AI cloud by enabling WCAG scans through driver capabilities. Framework-agnostic, works with Selenium, Playwright, and Cypress. Use when user mentions "accessibility", "a11y", "WCAG", "accessibility scan", "accessibility testing". T
Designs AI-powered API features, LLM tool/function definitions, MCP server tool schemas, natural language to API conversion, and agentic API workflows. Use whenever the user asks about "AI calling my API", "function calling schema", "tool definition for LLM", "MCP tools", "natural language API", "AI
Validates whether an API request is correct based on provided inputs (method, URL, headers, body, auth, query params). Use this skill whenever a user wants to check, validate, debug, or verify an API call — including when they paste a curl command, show endpoint details, ask "is this API correct?",
Designs GDPR-compliant API patterns, PCI-DSS field handling, SOC2 audit log schemas, HIPAA data endpoints, and regulatory compliance checklists for any API. Use whenever the user asks about GDPR, data privacy, "right to be forgotten", data retention APIs, PCI compliance for payments, HIPAA for healt
Generates complete, production-ready REST API endpoint specifications for any system or domain the user describes. Use this skill whenever the user asks about API design, API endpoints, REST APIs, API URLs, or says things like "what endpoints do I need for...", "design an API for...", "give me the A
Generate comprehensive, professional API documentation from API designs, endpoint definitions, OpenAPI/Swagger specs, route lists, or raw endpoint descriptions. Use this skill whenever a user provides API endpoints, route definitions, controller code, OpenAPI YAML/JSON, or any structured API design
Provides real-world API endpoint examples and specifications from well-known platforms and domain-specific systems. Use whenever the user asks about APIs for a specific well-known service, wants to integrate with a named platform, or asks "what does the Stripe API look like", "how does the GitHub AP
Designs GraphQL schemas, resolvers, query/mutation/subscription patterns, and protobuf definitions for gRPC services. Use whenever the user asks about GraphQL, "design a GraphQL schema", "write mutations for", "GraphQL subscriptions", "DataLoader pattern", "gRPC service", "protobuf definition", "pro
Related mobile skillsscan passed
PostHog error tracking for Flutter
Swift 6.2 Approachable Concurrency — single-threaded by default, @concurrent for explicit background offloading, isolated conformances for main actor types. Use when adopting Swift 6.2 concurrency — offloading with @concurrent or resolving main-actor isolation.
Regenerate the iOS debug bridge against the latest upstream gstack templates. (gstack)
Test iOS apps in a simulator with XcodeBuildMCP. Use when iOS changes need simulator evidence before handoff.
Manages Firebase Remote Config templates, feature flags, loading strategies, and SDKs (Android, iOS). Use when downloading/deploying remoteconfig JSON templates, managing version history/feature flags, setting in-app defaults, fetchAndActivate(), real-time listeners, or SDK setup. Don't use for Fire
AWS SDK for Swift development patterns. Use when writing Swift code that uses AWS services via aws-sdk-swift package.