Flutter projelerinde hızlı UI iterasyonu, gorunum bozulmalarini ve davranis regresyonlarini kolayca gozden kacirmamiza neden olabilir. Test ve golden testler, bu riski sistematik şekilde azaltir. Flutter test altyapisi uc ana katmanda dusunulur: hızlı ve izole unit test, widget agacini dogrulayan widget test ve gerçek cihaz veya emulatorde çalışan integration test. Golden testler ise piksel duzeyinde görsel regresyon yakalayan özel bir widget test turudur.
Test piramidi ve Flutter'a uyarlanmasi
Klasik test piramidinde tabanda cok sayida hızlı unit test, ortada widget testleri, tepede az sayida entegrasyon testi bulunur. Flutter'da widget testleri geleneksel UI testlerinden daha hızlı olduğu icin piramidin orta katmanı güçlü tutulabilir. Yine de ag aglantisi, izinler ve platform kanallari gerektiren akislarda integration test vazgecilmezdir.
Her katmanin sorumlulugunu karistirmamak önemlidir. Is mantigi unit testte; layout, etkileşim ve metin gosterimi widget testte; login, odeme ve push izni gibi uctan uca akislar integration testte dogrulanmalidir.
Widget testlerinin temelleri
flutter_test paketi WidgetTester ile widget agacini bellek icinde calistirir. Testlerde testWidgets blogu kullanılır, gerekli provider veya theme sarmalayicilari pumpWidget ile verilir.
testWidgets('Sepete ekle butonu sayaci artirir', (tester) async {
await tester.pumpWidget(
const MaterialApp(home: ProductDetailPage(productId: 'p1')),
);
await tester.tap(find.byKey(const Key('add_to_cart')));
await tester.pump();
expect(find.text('1'), findsOneWidget);
});
pump tek frame, pumpAndSettle animasyonlar bitene kadar bekler. Asiri uzun animasyonlarda settle timeout verebilir; bu durumda kontrollu pump(Duration) kullanmak daha stabildir.
Finders ve etkileşim kalıplari
find.text, find.byType, find.byKey en sik kullanilan buluculardir. Production kodunda test edilebilirlik icin kritik etkileşim noktalarina Key eklemek flakiness'i azaltir. Metin bazli arama, lokalizasyon degisince kirilgan olabilir; bu yuzden anlamli widget'lara key tercih edilir.
Mocking ve bağımlılık enjeksiyonu
Widget testlerinde gerçek API cagrilmamali. Repository arayuzunu mock veya fake ile değiştirmek gerekir. Riverpod'da ProviderScope(overrides: ...), get_it tabanli projelerde test modulune özel kayitlar kullanılır. Ag katmanı icin http.MockClient veya dio interceptor ile sabit cevaplar dondurulebilir.
Fake implementasyon, mock'tan daha okunabilir olabilir: bellek icinde map tutan basit bir FakeCartRepository çoğu senaryoyu yeterince kapsar.
Golden test nedir?
Golden test, widget'in belirli bir konfigurasyondaki goruntusunu PNG olarak kaydeder ve sonraki calistirmalarda pikselleri karsilastirir. Flutter'da matchesGoldenFile matcher'i ile yapilir. Görsel regresyonlari metin assertion'larindan once yakalamak icin güçlü bir aractir; özellikle tasarım sistemi bilesenleri, kart layout'lari ve ikon hizalamalari icin degerlidir.
testWidgets('PrimaryButton golden', (tester) async {
await tester.pumpWidget(
MaterialApp(
theme: AppTheme.light,
home: const Scaffold(
body: Center(child: PrimaryButton(label: 'Kaydet')),
),
),
);
await expectLater(
find.byType(PrimaryButton),
matchesGoldenFile('goldens/primary_button.png'),
);
});
Golden test icin en iyi uygulamalar
- Tutarlı cihaz boyutu:
tester.view.physicalSizevedevicePixelRatiosabitleyin - Font yükleme: custom font kullaniyorsaniz test basinda yukleyin
- Animasyonu durdurun veya settle oncesi sabit frame alin
- Platform farklarini ayri golden dosyalariyla yonetin
- Gurultulu görseller yerine izole bilesen golden'i tercih edin
Golden dosyalari repoda tutulur; bilincli tasarım degisikliginde flutter test --update-goldens ile güncellenir. CI pipeline'da golden testlerin deterministik calismasi icin ayni Flutter surumu ve ayni render ortami sarttir.
Flaky testleri azaltma
Flaky testler guveni eritir. Yaygın nedenler:
pumpAndSettlesonsuz animasyonlarda takilmasi- Gerçek zaman ve rastgele veri kullanımı
- Async gap sonrasi state'in dogrulanmamasi
- Global singleton'larin testler arasi kirli birakilmasi
fake_async paketi ile zaman kontrolu, her test oncesi dependency reset ve addTearDown ile temizlik flaky oranini dusurur.
Integration test ve integration_test paketi
integration_test paketi gerçek cihazda çalışır; Firebase Test Lab veya CI emulator farm ile birlestirilebilir. Uctan uca senaryolarda uygulama baslatma, login, navigasyon ve kritik işlem adimlari otomatiklestirilir. Widget testten farklı olarak platform kanallari ve gerçek disk IO devreye girer.
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('checkout akisi', (tester) async {
app.main();
await tester.pumpAndSettle();
await tester.tap(find.text('Odeme'));
await tester.pumpAndSettle();
expect(find.text('Siparis alindi'), findsOneWidget);
});
}
Test coverage ve anlamli metrik
flutter test --coverage ile lcov raporu uretilir. Yüzde hedefi tek basina yeterli degildir; kritik use case'lerin testlenip testlenmedigine bakin. Özellikle hata yollari, bos liste durumu ve offline mod gibi kenar senaryolar coverage'ta sik eksik kalir.
CI entegrasyonu
Pull request pipeline'inda unit ve widget testleri her commit'te calismali. Golden testler ayri job'da veya ayni job'da tutarlı Docker imaji ile kosulabilir. Integration testleri genellikle nightly veya release adayinda calistirmak maliyet dengesini sağlar. Test basarisizliginda anlasilir log ve screenshot artifact'leri debug suresini kisaltir.
Erisilebilirlik testleri
tester.ensureSemantics() ile semantics agaci uzerinden etiket ve rol dogrulamasi yapilabilir. Bu testler golden'dan farklı olarak ekran okuyucu uyumlulugunu kontrol eder. Button'larin anlamli label tasimasi, contrast ve focus sırası erisilebilirlik regresyonlarini erken yakalar.
Performans testleri
flutter drive ve timeline summary ile belirli akislarda frame oluşturma suresi olculer. Performans testleri her PR'da degil, kritik ekran degisikliklerinde calistirilmali. Scroll jank ve ilk frame suresi icin esik deger tanimlayip asildiginda build'i kirmak mumkundur.
Test verisi ve fixture yönetimi
JSON fixture dosyalarini test/fixtures altinda tutmak okunabilirligi artirir. Factory fonksiyonlarla örnek entity üretmek tekrar eden arrange adimlarini azaltir. Golden ve widget testlerinde ayni fixture setini paylasmak tutarlılık sağlar.
Ekip icin test kulturu
Testleri yalnizca QA'ya birakmak Flutter projelerinde sürdürülebilir degildir. Feature geliştirirken en az bir başarısız senaryo testi, bug fix'te regresyon testi yazmak standart olmalidir. Golden degisiklikleri code review'da görsel diff ile incelenmeli; "update goldens" butonu mekanik onaylanmamali.
Özet
Flutter'da kalite guvencesi; hızlı widget testleri, bilincli golden regresyonlari ve secili integration senaryolariyla insa edilir. Mock yerine fake, key bazli finder, sabit viewport ve CI'da deterministik ortam golden basarisinin temelidir. Test piramidini doğru dengelemek, hızlı geri bildirim ile gerçek dünya davranisini ayni anda garanti eder.
Golden testlerde metin render farklari icin sabit locale kullanın: MaterialApp locale parametresini tr_TR veya en_US olarak test basinda kilitleyin. Platform font fallback farklari yine de CI'da sorun cikarabilir; bu durumda flutter_test_config.dart ile global ayar yapin.
Snapshot test ile golden testi karistirmayin: snapshot genellikle widget tree string dump'idir, görsel regresyon yakalamaz. Her ikisi farklı amaclara hizmet eder.
Integration testlerde patlama riskini azaltmak icin test kullanıcısı ve mock backend'i staging ortaminda sabitleyin. Rastgele uretilen veri, store onay senaryolarinda bile regresyon üretir.
Test kodunda da production kalitesinde isimlendirme kullanmak, başarısız test loglarini okunur kilar. arrange-act-assert yorum bloklari yeni ekip uyeleri icin hiz kazandirir.
Widget testlerinde ag veya platform bagimliligini tamamen kesmek icin her dis servis icin arayüz tanimlayin. Bu sayede ayni test senaryosunu saniyeler icinde tekrar calistirabilirsiniz.
Golden dosya adlarinda ekran boyutu ve tema bilgisini suffix olarak kullanmak, farklı varyantlari duzenli tutar. Örneğin primary_button_light_375.png gibi isimlendirme review sirasinda karsilastirmayi kolaylastirir.
Test paketlerini feature modullerine yakın konumlandirmak yerine merkezi test/helpers altinda toplamak, tekrar eden pumpWidget ve tema sarmalama kodunu azaltir.
Her kritik bug fix icin once başarısız test ekleyip sonra duzeltmeyi uygulamak, ayni regresyonun bir sonraki surumde geri gelmesini engeller.