Как найти 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));
});
}