testing legacy strategies
3
总安装量
0
周安装量
#61577
全站排名
安装命令
npx skills add https://github.com/fwrite0920/android-skills --skill 'Testing Legacy Strategies'
Skill 文档
Testing Legacy Strategies (éçä»£ç æµè¯)
Instructions
- ä» å¨ç¼ºä¹æµè¯çæ¢æä»£ç ä¸ä½¿ç¨
- ä¾ç §ä¸æ¹ç« è顺åºå建å®å ¨ç½
- 䏿¬¡åªéå®ä¸ç±»è¡ä¸ºæè¾åº
- 宿åå¯¹ç § Quick Checklist
When to Use
- Scenario Cï¼æ§é¡¹ç®ç°ä»£ååçå®å ¨ç½
- Scenario Fï¼å ±äº«é»è¾éè¦æµè¯ä¿é
Example Prompts
- “请ä¾ç § Characterization Tests ç« èï¼æ¿è¿ä¸ªç±»å«å建ç°ç¶æµè¯”
- “ç¨ Robolectric ç« èï¼ä¸ºä¾èµ Framework ç Activity åæµè¯”
- “è¯·ç¨ Detekt/Lint Baseline ç« èåå»ºææ¯åºæ§ç®¡”
Workflow
- å å建 Characterization Tests éå®è¡ä¸º
- åè¡¥é½ Framework æµè¯ä¸ MockK çç¥
- æåç¨ Quick Checklist éªæ¶
Practical Notes (2026)
- æµè¯è¾åºå¿ é¡»å¯éå¤ä¸å¯æ¯å¯¹
- æ¯æ¬¡åªéå®ä¸ç±»è¡ä¸ºï¼é¿å æµè¯çé
- Baseline éæ¥æ¶æï¼é¿å 䏿¬¡æ§å¤§æ¹
Minimal Template
ç®æ :
æµè¯èå´:
è¡ä¸ºéå®:
å彿¹å¼:
éªæ¶: Quick Checklist
Characterization Tests (ç°ç¶æµè¯)
ä¸ºæ²¡ææµè¯çæ§ä»£ç æ°åãç°ç¶æµè¯ãï¼ä¸ç®¡å¯¹éï¼å éå®è¡ä¸ºã
çç¥
// 1. å
åä¸ä¸ªä¼å¤±è´¥çæµè¯
@Test
fun `calculateDiscount returns unknown value`() {
val result = legacyCalculator.calculateDiscount(100.0, "VIP")
assertEquals(0.0, result) // æ
æç¨é误ç颿å¼
}
// 2. è¿è¡æµè¯ï¼è®°å½å®é
åä¼ å¼
// AssertionError: expected 0.0 but was 15.0
// 3. æ´æ°æµè¯ä¸ºå®é
å¼
@Test
fun `calculateDiscount returns 15 percent for VIP`() {
val result = legacyCalculator.calculateDiscount(100.0, "VIP")
assertEquals(15.0, result) // éå®ç°æè¡ä¸º
}
æ¹éçæ
@ParameterizedTest
@CsvSource(
"100.0, VIP, 15.0",
"100.0, REGULAR, 5.0",
"50.0, VIP, 7.5"
)
fun `calculateDiscount characterization`(
price: Double,
tier: String,
expected: Double
) {
assertEquals(expected, legacyCalculator.calculateDiscount(price, tier))
}
Robolectric (Android Framework æµè¯)
å¤çé«åº¦ä¾èµ Android Framework çæ§åå æµè¯ã
设置
// build.gradle.kts
testImplementation("org.robolectric:robolectric:4.11.1")
// æµè¯ç±»å«
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [33])
class LegacyActivityTest {
@Test
fun `activity displays correct title`() {
val activity = Robolectric.buildActivity(LegacyActivity::class.java)
.create()
.resume()
.get()
assertEquals("Expected Title", activity.title)
}
}
Shadow 使ç¨
@Test
fun `shows toast on error`() {
activity.showError("Network failed")
val toast = ShadowToast.getLatestToast()
assertEquals("Network failed", ShadowToast.getTextOfLatestToast())
}
MockK for Kotlin
åºæ¬ç¨æ³
@Test
fun `repository returns cached data`() {
val repository = mockk<UserRepository>()
every { repository.getUser("123") } returns User(id = "123", name = "Test")
val result = repository.getUser("123")
assertEquals("Test", result.name)
verify { repository.getUser("123") }
}
Coroutines Support
@Test
fun `suspend function mocking`() = runTest {
val api = mockk<UserApi>()
coEvery { api.fetchUser("123") } returns User(id = "123")
val result = api.fetchUser("123")
coVerify { api.fetchUser("123") }
}
Relaxed Mocks
// èªå¨åä¼ é»è®¤å¼ï¼éåæ§ä»£ç æµè¯
val service = mockk<LegacyService>(relaxed = true)
Detekt/Lint Baseline
æ¸è¿å¼æ¶ç´§æ§é¡¹ç®çåè´¨æ åã
çæ Baseline
# Detekt
./gradlew detektBaseline
# 产ç config/detekt/baseline.xml
# Lint
./gradlew lintDebug -Dlint.baselines.continue=true
# 产ç lint-baseline.xml
åªæ£æ¥æ°ä»£ç
// build.gradle.kts
android {
lint {
baseline = file("lint-baseline.xml")
}
}
detekt {
baseline = file("config/detekt/baseline.xml")
}
æ¸è¿å¼ä¿®å¤
# æ¯ä¸ª Sprint åå° Baseline ä¸ç项ç®
# 1. ä¿®å¤ä¸æ¹é®é¢
# 2. éæ°çæ Baseline
./gradlew detektBaseline
Golden Master Testing
éå夿è¾åº (HTML, JSON) çæ§ä»£ç ã
@Test
fun `report generator produces expected output`() {
val output = legacyReportGenerator.generate(testData)
// 馿¬¡è¿è¡ï¼ä¿å为 golden file
// File("src/test/resources/golden/report.html").writeText(output)
// åç»è¿è¡ï¼æ¯å¯¹
val golden = File("src/test/resources/golden/report.html").readText()
assertEquals(golden, output)
}
Quick Checklist
- éæåå æ°å Characterization Tests
- ä½¿ç¨ Robolectric å¤ç Android ä¾èµ
- MockK ç relaxed mock å éæ§ä»£ç æµè¯
- Detekt/Lint Baseline æ§å¶ææ¯åº
- æ¯ä¸ª Sprint åå° Baseline 项ç®