Debugging dengan Safari Web Inspector (iOS) dan chrome://inspect (Android), logging native via Xcode/Logcat, unit test logic web, e2e dengan Appium/Detox-like approach, serta praktik trace bug yang hanya muncul di perangkat fisik.

Setelah di episode 17 kita membangun arsitektur offline-first, pada episode ini kita membahas testing dan debugging — dua aktivitas yang memakan waktu paling banyak dalam siklus development mobile. Bug yang hanya muncul di perangkat fisik dan tidak bisa direproduksi di browser adalah tantangan unik Capacitor.
Mengapa testing di perangkat penting? Karena WebView berperilaku berbeda di setiap versi OS. Fitur yang works di Chrome desktop bisa broken di WebView Android 12. Testing di perangkat nyata adalah satu-satunya cara memastikan aplikasi berjalan dengan benar.
Dari sini kalian bisa:
chrome://inspect/#devices.adb devices).Fitur yang tersedia:
xcrun simctl spawn booted log stream --level debug --predicate 'process == "MyApp"'Di Xcode, buka Output Console untuk melihat semua log dari simulator/device. Gunakan NSLog() atau os_log() di kode Swift untuk logging native.
adb logcat | grep -i "myapp"Di Android Studio, buka tab Logcat untuk melihat semua log dari emulator/device. Gunakan Log.d(), Log.e() di kode Kotlin untuk logging native.
Unit test untuk logika bisnis berjalan normal dengan Vitest atau Jest:
import { describe, it, expect } from 'vitest';
import { formatCurrency } from './utils';
describe('formatCurrency', () => {
it('formats IDR correctly', () => {
expect(formatCurrency(1500000)).toBe('Rp 1.500.000');
});
it('handles zero', () => {
expect(formatCurrency(0)).toBe('Rp 0');
});
});Untuk test kode yang memanggil plugin native:
import { vi } from 'vitest';
import { Preferences } from '@capacitor/preferences';
vi.mock('@capacitor/preferences', () => ({
Preferences: {
get: vi.fn().mockResolvedValue({ value: 'test-value' }),
set: vi.fn().mockResolvedValue(undefined),
remove: vi.fn().mockResolvedValue(undefined),
},
}));
it('reads preference', async () => {
const result = await Preferences.get({ key: 'test' });
expect(result.value).toBe('test-value');
});Appium adalah framework e2e untuk aplikasi mobile native dan hybrid:
npm install -g appium
appium driver install uiautomator2
appium driver install xcuitestimport { remote } from 'webdriverio';
async function testApp() {
const driver = await remote({
hostname: '127.0.0.1',
port: 4723,
capabilities: {
platformName: 'Android',
'appium:automationName': 'UiAutomator2',
'appium:app': 'path/to/app.apk',
},
});
// Cek elemen
const title = await driver.$('~home-title');
await expect(title).toHaveText('Welcome');
// Tap tombol
const button = await driver.$('~my-button');
await button.click();
await driver.deleteSession();
}Warning
E2E testing di Capacitor membutuhkan build native terlebih dahulu. Pastikan app sudah di-build (npx cap sync) sebelum menjalankan test.
Ketika bug hanya muncul di perangkat fisik:
console.log di setiap langkah.Tip
Beberapa bug hanya muncul di perangkat karena perbedaan WebView version, memory constraint, atau gesture handling. Selalu test di minimal satu perangkat fisik sebelum release.
Pada episode 18 ini, kalian telah memahami:
Di episode 19 selanjutnya, kita akan membahas CI/CD pipeline build aplikasi — GitHub Actions build signed IPA/APK, Fastlane untuk signing dan build, Ionic Appflow sebagai managed option, serta keamanan secrets di CI. Sampai jumpa!