Membangun strategi testing untuk aplikasi mobile: pyramid testing, unit test untuk logika bisnis, widget/UI tests di tiap framework, dan e2e dengan Detox/Maestro/Appium — sambil menyusun test suite Fitku yang cepat dan andal

Sejauh ini kita membangun banyak fitur — kini saatnya memastikan fitur itu tetap benar saat aplikasi tumbuh. Di episode 16 ini kita belajar testing mobile: unit test untuk logika, widget/UI tests untuk perilaku tampilan, dan end-to-end (e2e) untuk alur pengguna yang utuh. Arsitektur yang rapi (episode 8) mulai membayar di sini.
Mengapa testing wajib? Karena aplikasi tanpa test adalah bom waktu: satu perubahan kecil bisa merusak fitur jauh yang tidak disadari, dan regresi hanya ketahuan setelah pengguna mengeluh di review store. Test adalah jaring pengaman yang membuat refactor dan penambahan fitur tetap aman.
Strategi testing yang sehat mengikuti test pyramid: banyak unit test (cepat, murah), sedang integration/widget, sedikit e2e (lambat, mahal).
/\ e2e (detox/maestro) — sedikit, alur kritis
/ \ widget/UI test — menengah
/ \ unit test — banyak, logika bisnis| Jenis | Kecepatan | Stabilitas | Lingkup |
|---|---|---|---|
| Unit | Sangat cepat | Sangat stabil | Logika, reducer, repository |
| Widget/UI | Cepat | Stabil | Perilaku satu layar |
| E2E | Lambat | Rapuh | Alur utuh lintas layar |
Unit test menguji logika murni tanpa device — reducer MVI (episode 8) adalah kandidat sempurna:
class HomeReducerTest {
@Test
fun `refresh mengisi steps dari source`() {
val state = HomeState()
val newState = homeReducer(state, HomeIntent.Refresh)
assertEquals(1234, newState.steps)
}
@Test
fun `kalkulasi kalori HIGH benar`() {
val workout = Workout("Lari", 30, Intensity.HIGH)
assertEquals(58.5, workout.caloriesBurned(65.0), 0.01)
}
}final class CaloriesTests: XCTestCase {
func testHighIntensityBurnsCorrectly() {
let workout = Workout(name: "Lari", durationMinutes: 30, intensity: .high)
XCTAssertEqual(workout.caloriesBurned(weightKg: 65.0), 58.5, accuracy: 0.01)
}
}Logika murni di Dart diuji tanpa widget; di RN, logika reducer/store Zustand diuji dengan Vitest biasa — hasilnya: tes berjalan milidetik tanpa emulator.
Tip
Kuncinya: pisahkan logika dari framework (arsitektur episode 8). Semakin banyak logika di layer domain murni, semakin banyak yang bisa diuji tanpa device — dan semakin sedikit test yang perlu dijalankan di emulator yang lambat.
Test di tingkat tampilan: render layar, beri input, cek hasil. Lebih lambat dari unit, tapi memvalidasi perilaku UI.
@RunWith(AndroidJUnit4::class)
class HomeScreenTest {
@get:Rule
val composeRule = createComposeRule()
@Test
fun `tombol tambah langkah menambah counter`() {
composeRule.setContent { StepCounter() }
composeRule.onNodeWithText("0").assertIsDisplayed()
composeRule.onNodeWithText("Tambah langkah").performClick()
composeRule.onNodeWithText("1").assertIsDisplayed()
}
}func testTapAddStepIncrementsCounter() {
let app = XCUIApplication()
app.launch()
app.staticTexts["0"].assertExists()
app.buttons["Tambah langkah"].tap()
app.staticTexts["1"].assertExists()
}testWidgets('tombol menambah langkah', (tester) async {
await tester.pumpWidget(const StepCounter());
expect(find.text('0'), findsOneWidget);
await tester.tap(find.text('Tambah langkah'));
await tester.pump();
expect(find.text('1'), findsOneWidget);
});E2e menguji aplikasi yang benar-benar berjalan di device/emulator, melewati UI nyata — termasuk navigasi, network, dan integrasi. Tools populer 2026: Maestro (sederhana, YAML), Detox (RN), Appium (fleksibel).
appId: dev.fitku.app
---
- launchApp
- assertVisible: "Halo, Fitku!"
- tapOn: "Tambah langkah"
- assertVisible: "1"
- tapOn: "Progres"
- assertVisible: "Grafik mingguan"maestro test flow.yaml langsung menjalankannya di emulator. Untuk RN, Detox memberi determinisme yang kuat dengan synchronization otomatis.
Warning
E2E itu rapuh dan mahal — jangan jadikan primary gate. Jalankan e2e di pipeline CI (episode 17) untuk alur kritis (login → workout → sync) dan biarkan unit/widget menangani 90% sisanya. Jika e2e memakan waktu lebih dari 10-15 menit, audit mana alur yang benar-benar butuh e2e.
Integrasikan test ke pipeline (dibahas penuh episode 17):
Lint & static check → cepat, di setiap push
Unit test → cepat, di setiap push
Widget/UI test → menengah, di pull request
E2E (Maestro/Detox) → lambat, sebelum releasePada episode 16 ini, kalian telah membangun fondasi kualitas:
Di episode 17 selanjutnya kita otomatisasi semuanya: CI/CD & Release Pipeline — GitHub Actions, Fastlane, dan build signing untuk rilis Fitku yang repetitif tanpa error. Sampai jumpa!