Как найти FlatButton.icon в тестах Flutter?

В своем приложении я создаю кнопку, используя FlatButton.icon(Документы Flutter). Сейчас пытаюсь найти кнопку во время тестирования.

я пытался

find.byType(MaterialButton); // -> zero widgets
find.byType(FlatButton); // -> zero widget

Странно то, что я могу найти текст для кнопки

find.text('my button text');

и я также могу найти значок кнопки

find.byType('Icon');

Я не уверен, что мне нужно искать, чтобы найти кнопку.

6 ответов

Хорошо, я не смог найти сам FlatButton, но значок легко найти с помощью. . .

find.byIcon(Icons.yourIcon);

См. Соответствующие документы для получения дополнительной информации: flutter_test find.byIcon

Хотя вопрос может показаться довольно старым, я хотел бы расширить тему, поскольку ни один из ответов на самом деле не показывает, как найти сам FlatButton. Проблема в том, что FlatButton.icon не конструктор, а фабрика, создающая другой объект _FlatButtonWithIcon расширение FlatButton, который, по-видимому, доступен только внутри его файла. В это время, find.byType ищет только виджеты идентичного типа - это не работает для производных типов.

Итак, чтобы вернуть сам объект: find.ancestor(of: find.byIcon(Icons.your_icon), matching: find.byWidgetPredicate((widget) => widget is FlatButton)). Такой подход позволил нам получить объект кнопки и, следовательно, протестировать его свойства (например, onPressed) или дочерние виджеты (например, label) позвонив find.descendant.

Следующий код (я столкнулся с этой проблемой и получил некоторую помощь от сервера разногласий флаттера...) не работал. Вот правильный тестовый код. Исправление находится в последней строке.

      import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('TextButton.icon test', (WidgetTester tester) async {
    const IconData iconData = Icons.add;

    await tester.pumpWidget(
      MaterialApp(
        home: Center(
          child: TextButton.icon(
            onPressed: () { },
            icon: const Icon(iconData),
            label: const Text('text button'),
          ),
        ),
      ),
    );
    final dynamic textButtonWithIconWidget = tester.widget(find.byWidgetPredicate((Widget widget) => '${widget.runtimeType}' == '_TextButtonWithIconChild'));
    expect(textButtonWithIconWidget.icon.icon, iconData); // MODIFIED CODE. NOW WORKS !
  });
}

Ответ Олега сработал для меня, затем я применил некоторые дженерики, чтобы получить следующую функцию для моего варианта использования. Я пытался найти кнопку, сгенерированную ElevatedButton.icon(), но этот подход может работать и с другой кнопкой со значком.

      Finder widgetWithText<T>(String text) {
    return find.ancestor(
        of: find.text(text),
        matching: find.byWidgetPredicate((widget) => widget is T));
}

Тестовый код выглядит так:

      final textFinder = widgetWithText<ElevatedButton>('Like');
void main() {
  testWidgets('find one FlatButton', (WidgetTester tester) async {
    await tester.pumpWidget(FlatButton.icon(
        onPressed: (){},
        icon: Icon(Icons.access_alarm),
        label: Text('remind me')
    ));
    expect(find.byType(FlatButton), findsOneWidget);
    expect(find.text('remind me'), findsOneWidget)
  });
}

затем запустите команду проверки флаттера в терминале

00:02 +1: All tests passed!

виджет, который вы хотите протестировать, должен быть сгенерирован методом tester.pumpWidget.

https://flutter.dev/docs/cookbook/testing/widget/introduction

Я столкнулся с этой проблемой и получил некоторую помощь от сервера разногласий флаттера, и здесь я делюсь решением: ПРИМЕЧАНИЕ: вы должны использовать динамический для возвращаемого виджета, потому что класс является закрытым.

      void main() {
  testWidgets('TextButton.icon test', (WidgetTester tester) async {
    const IconData iconData = Icons.add;

    await tester.pumpWidget(
      MaterialApp(
        home: Center(
          child: TextButton.icon(
            onPressed: () { },
            icon: const Icon(iconData),
            label: const Text('text button'),
          ),
        ),
      ),
    );
    final dynamic textButtonWithIconWidget = tester.widget(find.byWidgetPredicate((Widget widget) => '${widget.runtimeType}' == '_TextButtonWithIconChild'));
    expect(textButtonWithIconWidget.icon, const Icon(iconData));
  });
}
Другие вопросы по тегам