android-tdd/SKILL.md
Android Test-Driven Development standards. Enforces Red-Green-Refactor cycle, test pyramid (70/20/10), layer-specific testing strategies, and CI integration. Use when building or reviewing Android apps with TDD methodology.
npx skillsauth add peterbamuhigire/skills-web-dev android-tddInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
android-tdd or would be better handled by a more specific companion skill.references only as needed.SKILL.md first, then load only the referenced deep-dive files that are necessary for the task.references/ directory for deep detail after reading the core workflow below.TDD is a development process where you write tests before feature code, following the Red-Green-Refactor cycle. Every feature starts with a failing test, gets minimal implementation, then is refined.
Core Principle: No production code without a failing test first.
Icon Policy: If UI code is generated as part of TDD, use custom PNG icons and maintain PROJECT_ICONS.md (see android-custom-icons).
Report Table Policy: If UI tests cover reports that can exceed 25 rows, the UI must use table layouts (see android-report-tables).
| Topic | Reference File | When to Use |
| ----------------------- | ----------------------------------- | ------------------------------------------------- |
| TDD Workflow | references/tdd-workflow.md | Step-by-step Red-Green-Refactor with examples |
| Testing by Layer | references/testing-by-layer.md | Unit, integration, persistence, network, UI tests |
| Advanced Techniques | references/advanced-techniques.md | Factories, behavior verification, LiveData/Flow |
| Tools & CI Setup | references/tools-and-ci.md | Dependencies, CI pipelines, test configuration |
| Team Adoption | references/team-adoption.md | Legacy code, team onboarding, troubleshooting |
1. RED → Write a failing test for desired behavior
2. GREEN → Write MINIMUM code to make it pass
3. REFACTOR → Clean up while keeping tests green
4. REPEAT → Next behavior
Critical Rules:
/ UI \ 10% - Espresso, end-to-end flows
/--------\
/ Integra- \ 20% - ViewModel+Repository, Room, API
/ tion \
/--------------\
/ Unit Tests \ 70% - Pure Kotlin, fast, isolated
/==================\
| Type | Speed | Scope | Location | Tools |
| --------------- | ----------- | ---------------------- | ------------------------- | ------------------------- |
| Unit | <1ms each | Single class/method | test/ | JUnit, Mockito |
| Integration | ~100ms each | Component interactions | test/ or androidTest/ | JUnit, Robolectric |
| UI | ~1s each | User flows | androidTest/ | Espresso, Compose Testing |
Start with a clear user story or acceptance criteria:
As a user, I want to add items to my cart so I can purchase them later.
@Test
fun addItemToCart_increasesCartCount() {
val cart = ShoppingCart()
cart.addItem(Product("Phone", 999.99))
assertEquals(1, cart.itemCount)
}
Run it. It must fail (class doesn't exist yet).
class ShoppingCart {
private val items = mutableListOf<Product>()
fun addItem(product: Product) { items.add(product) }
val itemCount: Int get() = items.size
}
Run test. It passes. Stop writing code.
@Test
fun addMultipleItems_calculatesTotal() {
val cart = ShoppingCart()
cart.addItem(Product("Phone", 999.99))
cart.addItem(Product("Case", 29.99))
assertEquals(1029.98, cart.totalPrice, 0.01)
}
Implement totalPrice, then refactor both test and production code.
class ScoreTest {
@Test
fun increment_increasesCurrentScore() {
val score = Score()
score.increment()
assertEquals(1, score.current)
}
}
@RunWith(AndroidJUnit4::class)
class WishlistDaoTest {
private lateinit var db: AppDatabase
@Before
fun setup() {
db = Room.inMemoryDatabaseBuilder(
ApplicationProvider.getApplicationContext(),
AppDatabase::class.java
).build()
}
@After
fun teardown() { db.close() }
}
class ApiServiceTest {
private val mockWebServer = MockWebServer()
@Test
fun fetchData_returnsExpectedResponse() {
mockWebServer.enqueue(
MockResponse().setBody("""{"id":1,"name":"Test"}""").setResponseCode(200)
)
val response = service.fetchData().execute()
assertEquals("Test", response.body()?.name)
}
}
@Test
fun clickSaveButton_showsConfirmation() {
onView(withId(R.id.saveButton)).perform(click())
onView(withText("Saved!")).check(matches(isDisplayed()))
}
dependencies {
// Unit
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito.kotlin:mockito-kotlin:5.2.1'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
// Integration & UI
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.arch.core:core-testing:2.2.0'
// Room & Network
testImplementation 'androidx.room:room-testing:2.6.1'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.12.0'
}
Use descriptive names following: methodUnderTest_condition_expectedResult
fun addItem_emptyCart_cartHasOneItem()
fun calculateTotal_multipleItems_returnsSumOfPrices()
fun login_invalidCredentials_returnsError()
fun fetchUsers_networkError_showsErrorState()
feature-planning → Define specs & acceptance criteria
↓
android-tdd → Write tests first, then implement (THIS SKILL)
↓
android-development → Follow architecture & Kotlin standards
↓
ai-error-handling → Validate AI-generated implementations
↓
vibe-security-skill → Security review
Key Integrations:
name: Android TDD
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Unit Tests
run: ./gradlew test
- name: Instrumented Tests
run: ./gradlew connectedAndroidTest
- name: Coverage Report
run: ./gradlew jacocoTestReport
CI Rules:
data-ai
Use when adding AI-powered analytics to a SaaS platform — semantic search over business data, natural language queries, trend detection, anomaly alerts, and AI-generated insights for dashboards. Covers embeddings, NL2SQL, and per-tenant analytics...
data-ai
Design AI-powered analytics dashboards — what metrics to show, how to display AI predictions and confidence, drill-down patterns, KPI cards, trend visualisation, AI Insights panels, export design, and role-based dashboard variants. Invoke when...
development
Use when designing, building, reviewing, or upgrading production software systems that must be secure, performant, maintainable, scalable, and user-centered. Apply before writing specs, code, architecture, APIs, databases, mobile apps, SaaS platforms, or ERP systems.
development
Professional web app UI using commercial templates (Tabler/Bootstrap 5) with strong frontend design direction when needed. Use for CRUD interfaces, dashboards, admin panels with SweetAlert2, DataTables, Flatpickr. Clone seeder-page.php, use...