DEV Community

Cover image for Flutter Entegrasyon Testi | Bölüm 2
Gülsen Keskin
Gülsen Keskin

Posted on • Updated on

Flutter Entegrasyon Testi | Bölüm 2

Widget Tester Methodları: Test ortamında widget'lar oluşturmayı ve bu widget'lar ile etkileşime girmeyi sağlar.

testWidgets() fonksiyonu, her test case'i için otomatik olarak yeni bir WidgetTester oluşturur.

Finders: Finder class'ları, test ortamında widget'ların aranmasını sağlar.

Matchers: Widget'a özgü Matcher sabitleri, Finder'ın test ortamında bir widget'ı mı yoksa birden fazla widget'ı mı bulduğunu doğrulamaya yardımcı olur.

testWidgets() fonksiyonu

Bir testi tanımlamak için flutter_test paketi tarafından sağlanan testWidgets() fonksiyonu kullanılır. testWidgets fonksiyonu, bir widget testi tanımlamanıza ve birlikte çalışmak için bir WidgetTester oluşturmanıza olanak tanır.

örnek:

void main() {
  testWidgets('test açıklaması', (tester) async {
// Test kodu buraya gelir.
  });
}
Enter fullscreen mode Exit fullscreen mode

WidgetTester'ı kullanarak widget oluşturmak
Ardından, WidgetTester tarafından sağlanan pumpWidget() methodunu kullanarak MyWidget'ı test ortamı içinde oluşturun. pumpWidget methodu, sağlanan widget'ı oluşturur ve işler.

pumpWidget()'a yapılan ilk çağrıdan sonra, WidgetTester aynı parçacığı yeniden oluşturmak için ek yollar sağlar. Bu, bir StatefulWidget veya animasyonlarla çalışıyorsanız kullanışlıdır.

Örneğin, bir butona dokunmak setState() öğesini çağırır, ancak Flutter test ortamında widget'ınızı otomatik olarak yeniden oluşturmaz. Flutter'dan widget'ı yeniden oluşturmasını istemek için aşağıdaki yöntemlerden birini kullanın.

tester.pump(Duration duration)
tester.pumpAndSettle(): Verilen süre boyunca tekrar tekrar pump()'ı çağırır. Bu, esasen, tüm animasyonların tamamlanmasını bekler.

expect(actual, matcher);

Bir widget'ın mevcut olup olmadığını kontrol etmek istiyorsanız expect methodunu kullanabilirsiniz.

Örneğin API'ye kayıt işleminden sonra "İşlem başarılı" mesajı gösteren bir uygulamanız olduğunu düşünün. Bu durumda bu mesajın görünüp görünmediğini kontrol etmek için expect methodunu kullanabilirsiniz.

actual parametresi finder değeri alır, matcher parametresi ise eşleşme düzeyini belirtir.

Örnek senaryomuzdan devam edecek olursak 1 adet "İşlem başarılı" mesajının mevcut olup olmadığını kontrol etmek istersek:

final Finder successTxtFinder= find.text('Kayıt Başarılı');

expect(successTxtFinder, findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

Buradaki findsOneWidget parametresi ile kastedilen şey finder'ın "Kayıt başarılı" mesajından bir tane bulması gerektiğidir. Aynı mesajdan birden fazla bulunması durumunda testimiz hata verir. Bulucunun(finder) bir veya daha fazla widget bulmasını istediğinizde findsWidgets parametresini kullanabilirsiniz.

Matchers

Eşleştirici(Matchers) sınıfları, test paketinin temel bir parçasıdır ve belirli bir değerin beklentileri karşıladığını doğrulamak için ortak bir yol sağlar.

findsWidgets: bulucunun (finder) bir veya daha fazla widget bulmasını istediğinizde findsWidgets parametresini,
findsOneWidget: bulucunun tam olarak bir widget bulmasını istediğinizde parametresini,
findsNWidgets: bulucunun widget ağacında belirtilen sayı kadar widget'ı bulmasını istediğinizde,
findsAtLeastNWidgets: bulucunun en azından belirli sayıda widget bulmasını istediğinizde ise findsAtLeastNWidgets parametresini kullanabilirsiniz.
matchesGoldenFile: Bir widget'ın oluşturma işleminin belirli bir bitmap görüntüsüyle eşleştiğini doğrular.

Save text'inden hiç bulunmaması durmu

 expect(find.text('Save'), findsNothing); 
Enter fullscreen mode Exit fullscreen mode

Save text'inin 1 kez bulunması durmu

 expect(find.text('Save'), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

Save text'inden widget ağacında tam olarak 2 tane bulunması durumu

expect(find.text('Save'), findsNWidgets(2));
Enter fullscreen mode Exit fullscreen mode

Save text'inden widget ağacında en az 2 tane bulunması durumu

expect(find.text('Save'), findsAtLeastNWidgets(2));
Enter fullscreen mode Exit fullscreen mode

Yaygın kullanılan finder methodları

flutter_test paketi tarafından sağlanan find constant'ı, test ortamında widget'ların yerini belirlemenin birkaç yolunu sağlar.

byElementType: Belirli bir türdeki öğeleri arayarak widget'ları bulur.

Örneğin text tipinde bir widget'ı aramak için:

expect(find.byElementType(Text), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

byIcon: Parametre olarak verilen icon'u arar.

expect(find.byIcon(Icons.inbox), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

**byKey:" Parametre olarak aldığı anahtar(key) değerine sahip olan widget'ı arar.

expect(find.byKey(const Key("your_key")), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

örnek:

testWidgets('finds a widget using a Key', (tester) async {
// Test key tanımlayın.
  const testKey = Key('K');

// testKey ile bir MaterialApp oluşturun.
  await tester.pumpWidget(MaterialApp(key: testKey, home: Container()));

  // testKey'i kullanarak MaterialApp widget'ını bulun.
  expect(find.byKey(testKey), findsOneWidget);
});
Enter fullscreen mode Exit fullscreen mode

bySemanticsLabel: RegExp.hasMatch veya string eşitliği ile verilen label ile eşleşen Semantik widget'larını bulur.

expect(find.bySemanticsLabel('Back'), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

bySubtype: Belirli bir türü uygulayan widget'ları arar.

Bu eşleştirici alt türleri kabul eder. Örneğin, bir bySubtype() herhangi bir stateful widget'ı bulacaktır.

expect(find.bySubtype<IconButton>(), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

byTooltip: Verilen mesajla Tooltip widget'larını bulur.

expect(find.byTooltip('Back'), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

byType: Parametre olarak aldığı türe sahip olan widgetları arar.

expect(find.byType(IconButton), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

byWidget: Parametre olarak verilen widget'ı arar.

// Böyle bir butonunuz olduğunu varsayalım
Widget myButton = Button(
  child: Text('Update')
);

// Bu şekilde bulabilir ve üzerine tıklayabilirsiniz:
tester.tap(find.byWidget(myButton));
Enter fullscreen mode Exit fullscreen mode

bir diğer örnek:

testWidgets('finds a specific instance', (tester) async {
  const childWidget = Padding(padding: EdgeInsets.zero);

  await tester.pumpWidget(Container(child: childWidget));

 expect(find.byWidget(childWidget), findsOneWidget);
});
Enter fullscreen mode Exit fullscreen mode

byWidgetPredicate: Bir widget predicate'i kullanarak widget'ları bulur.

expect(find.byWidgetPredicate(
  (Widget widget) => widget is Tooltip && widget.message == 'Back',
  description: 'widget with tooltip "Back"',
), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

image:
Verilen image parametresiyle aynı resmi içeren Image ve FadeInImage widget'larını döndürür.

expect(find.image(FileImage(File(filePath))), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

text:
Parametre olarak aldığı metin değeriyle eşleşen (birebir aynı metin olmaları gerekir) Text, EditableText ve RichText widget'larını arar.

findRichText parametresi false ise, tüm bağımsız RichText widget'ları yok sayılır ve metin Text.data veya Text.textSpan ile eşleştirilir. findRichText parametresi true ise, RichText widget'ları (ve dolayısıyla Text ve Text.rich widget'ları), InlineSpan.toPlainText verilen metinle karşılaştırılarak eşleştirilir.

EditableText widget'ları için metin her zaman EditableText.controller'ın geçerli değeriyle karşılaştırılır.

"Back" string'ini içeren Text, Text.rich ve EditableText widget'larını bulur.

expect(find.text('Back'), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

"Close" string'ini içeren Text, Text.rich, EditableText, ve RichText widget'larını bulur.

expect(find.text('Close', findRichText: true), findsOneWidget);
Enter fullscreen mode Exit fullscreen mode

textContaining: parametre olarak aldığı metin değerini içerin Text, EditableText ve RichText widget'larını arar.

findRichText parametresi false ise, tüm bağımsız RichText widget'ları yok sayılır ve metin Text.data veya Text.textSpan ile eşleştirilir. findRichText parametresi true ise, RichText widget'ları (ve dolayısıyla Text ve Text.rich widget'ları), InlineSpan.toPlainText verilen string ile karşılaştırılarak eşleştirilir.

EditableText widget'ları için desen her zaman EditableText.controller'ın mevcut değeriyle karşılaştırılır.

widgetWithIcon:

Parametre olarak aldığı widget ve icon değeriyle eşleşen widget'ları bulur.

// İçinde 'arrow_forward' ikonu olan bir butonunuz olduğunu varsayalım:
Button(
  child: Icon(Icons.arrow_forward)
)

// Bu şekilde bulabilir ve üzerine dokunabilirsiniz:
tester.tap(find.widgetWithIcon(Button, Icons.arrow_forward));
Enter fullscreen mode Exit fullscreen mode

widgetWithImage:
Parametre olarak aldığı widget ve resim değeriyle eşleşen widget'ları bulur.

// İçinde resim olan bir butonunuz olduğunu varsayalım:
Button(
  child: Image.file(filePath)
)

// Bu şekilde bulabilir ve üzerine dokunabilirsiniz:
tester.tap(find.widgetWithImage(Button, FileImage(filePath)));
Enter fullscreen mode Exit fullscreen mode

widgetWithText: Parametre olarak aldığı widget ve onun child'ı olan Text widget'ının metin değeriyle eşleşen widget'ları bulur.

// İçinde 'Güncelle' yazan bir butonunuz olduğunu varsayalım:
Button(
  child: Text('Update')
)

// Bu şekilde bulabilir ve üzerine dokunabilirsiniz:
tester.tap(find.widgetWithText(Button, 'Update'));
Enter fullscreen mode Exit fullscreen mode

WidgetTester Methodları

pumpWidget: Widget'ı build eder

enterText: TextField'a metin girmeyi sağlar.

testWidgets('Add and remove a todo', (tester) async {
  await tester.pumpWidget(const TodoList());

  // TextField'e 'hi' yazar.
  await tester.enterText(find.byType(TextField), 'hi');
});
Enter fullscreen mode Exit fullscreen mode

dragFrom: Verilen ofsete göre kaydırma hareketi uygular.

tester.drag(finder, offset)
Enter fullscreen mode Exit fullscreen mode
testWidgets('Add and remove a todo', (tester) async {

// Kapatmak için öğeyi kaydırın.
  await tester.drag(find.byType(Dismissible), const Offset(500.0, 0.0));

// Kapatma animasyonu bitene kadar widget'ı oluşturun.
  await tester.pumpAndSettle();

// Öğenin artık ekranda olmadığından emin olun.
  expect(find.text('hi'), findsNothing);
});
Enter fullscreen mode Exit fullscreen mode

dragUntilVisible: Finder görüntülenene kadar kaydırma hareketini yineler.

moveStep kadar sürükleme işlemi denendikten sonra finder bulunamazsa bir StateError atar.

tester.dragUntilVisible(finder, view, moveStep)
Enter fullscreen mode Exit fullscreen mode

tap: Parametre olarak aldığı finder değeriyle eşleşen widget'a dokunur.

await tester.tap(find.byType(FloatingActionButton));
Enter fullscreen mode Exit fullscreen mode

ensureVisible: Parametre olarak aldığı finder değerini buluna kadar widget'ı kaydırır.

      await tester.ensureVisible(find.text("Gülsen")); //Gülsen yazısını buluncaya kadar ekranı kaydırır.
Enter fullscreen mode Exit fullscreen mode

longPress: Parametre olarak aldığı finder değeriyle eşleşen widget a uzun süre dokunur.

pageBack: Scaffold'daki geri düğmesine dokunur.

press: Parametre olarak aldığı finder değeriyle eşleşen widget'ın ortasına dokunur.

printToConsole: Verilen mesajla debugPrint'i çağırır.

restartAndRestore: Uygulama yeniden başlatıldıktan sonra widget ağacının state'ini geri yüklemeyi simüle eder.

scrollUntilVisible: Parametre olarak aldığı finder değeriyle eşleşen widget görüntüleninceye kadar Scrollable.axisDirection yönünde kaydırma işlemi uygular.

Bu, henüz oluşturulmamış finder'ı aramanıza izin vermesi bakımından ensureVisible'dan farklıdır.

Resources: https://github.com/flutter/flutter/blob/master/packages/flutter_test/lib/src/matchers.dart
https://api.flutter.dev/flutter/flutter_test/flutter_test-library.html
https://api.flutter.dev/flutter/flutter_test/WidgetTester-class.html
https://docs.flutter.dev/cookbook/testing/widget/tap-drag
https://docs.flutter.dev/cookbook/testing/widget/introduction

Discussion (0)