Belajar Mobile Developer - Testing Mobile
Episode 16 of 28

Belajar Mobile Developer - Testing Mobile

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

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

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.

Pyramid Testing

Strategi testing yang sehat mengikuti test pyramid: banyak unit test (cepat, murah), sedang integration/widget, sedikit e2e (lambat, mahal).

Test pyramid mobile
      /\        e2e (detox/maestro) — sedikit, alur kritis
     /  \       widget/UI test — menengah
    /    \      unit test — banyak, logika bisnis
JenisKecepatanStabilitasLingkup
UnitSangat cepatSangat stabilLogika, reducer, repository
Widget/UICepatStabilPerilaku satu layar
E2ELambatRapuhAlur utuh lintas layar

Unit Test

Unit test menguji logika murni tanpa device — reducer MVI (episode 8) adalah kandidat sempurna:

Kotlin (JUnit)

KotlinUnit test reducer di Kotlin
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)
    }
}

Swift (XCTest)

Unit test di Swift
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)
    }
}

Dart (flutter_test) & TypeScript (Vitest/Jest)

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.

Widget / UI Test

Test di tingkat tampilan: render layar, beri input, cek hasil. Lebih lambat dari unit, tapi memvalidasi perilaku UI.

Compose (androidTest)

KotlinUI test Compose
@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()
    }
}

SwiftUI (XCUITest)

UI test di XCUITest
func testTapAddStepIncrementsCounter() {
    let app = XCUIApplication()
    app.launch()
 
    app.staticTexts["0"].assertExists()
    app.buttons["Tambah langkah"].tap()
    app.staticTexts["1"].assertExists()
}

Flutter widget test

Widget test Flutter
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);
});

End-to-End (E2E)

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).

Maestro flow: Fitku
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.

CI Integration

Integrasikan test ke pipeline (dibahas penuh episode 17):

Lapisan test di CI
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 release

Common Pitfalls Testing

  • Menguji implementasi, bukan perilaku: test harus bertahan saat refactor internal, hanya berubah saat perilaku berubah.
  • Timing-dependent tests: test yang bergantung pada waktu nyata membuat flaky — gunakan fake clocks dan mock.
  • Mengabaikan logika di UI: semua logika pindah ke layer testable (episode 8).
  • Menutup mata pada test yang flaky: flaky test yang diabaikan akhirnya di-skip semua orang — hapus atau perbaiki.
  • Tidak memakai coverage secara bijak: coverage 100% tanpa kualitas tidak berharga; fokus pada jalur kritis.

Penutup

Pada episode 16 ini, kalian telah membangun fondasi kualitas:

  • Test pyramid: banyak unit, menengah widget/UI, sedikit e2e.
  • Unit test untuk reducer & logika murni di Kotlin/Swift/Dart/TS.
  • Widget/UI test di Compose, XCUITest, dan flutter_test.
  • E2E dengan Maestro/Detox/Appium untuk alur kritis.
  • Test terintegrasi ke CI sebagai gerbang 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!

Belajar Mobile Developer - Testing Mobile | Belajar Mobile Developer