#flutter #dart #testing
Вопрос:
У меня есть этот виджет:
class _DemoWidget extends State<DemoWidget> {
Choices? _selectedChoice;
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
createTile(
'The First Option', Choices.FRIENDS, const Key('firstOption')),
if (_selectedChoice == Choices.FIRST)
TextFormField(
key: const Key('searchFirst'),
),
createTile('The Second Option', Choices.CONTACT, const Key('secondOption')),
if (_selectedChoice == Choices.SECOND)
TextFormField(
key: const Key('searchSecond'),
),
],
),
);
}
RadioListTile<Choices> createTile(String title, Choices choice, Key key) {
return RadioListTile<Choices>(
key: key,
title: Text(
title,
),
value: choice,
groupValue: _selectedChoice,
onChanged: (Choices? val) => setState(() => _selectedChoice = val),
);
}
}
Он имеет две переключатели, и в зависимости от того, какая кнопка в данный момент активна, он отобразит текстовое поле ниже этой опции. Я пытаюсь создать тест на такое поведение и начал с этого:
testWidgets('Clicking on person search opens up textfield',
(WidgetTester tester) async {
await tester.pumpWidget(
renderWith(),
);
Finder firstOption = find.text('The First Option');
await tester.tap(firstOption);
expect(find.byKey(const Key('searchFirst')), findsOneWidget);
}, skip: false);
но каждый раз получал бы тест на сбой, затем я добавил продолжительность между касанием и обеспечением видимости
testWidgets('Clicking on person search opens up textfield',
(WidgetTester tester) async {
await tester.pumpWidget(
renderWith(),
);
Finder firstOption = find.text('The First Option');
await tester.tap(firstOption);
await tester.pump(Duration(milliseconds: 50));
tester.ensureVisible(find.byKey(const Key('searchFirst')));
expect(find.byKey(const Key('searchFirst')), findsOneWidget);
}, skip: false);
и испытание проходит.
Я думаю, что использование тайм-аутов не кажется очень безопасным способом тестирования, но в некоторых местах я читал, что это требуется для некоторых виджетов flutter. Есть ли какой-то способ выполнить этот тест без необходимости закачивать время ожидания в тестер?
Ответ №1:
Согласно документации Flutter, вам просто нужно использовать pump
:
Finder firstOption = find.text('The First Option');
await tester.tap(firstOption);
await tester.pump();
Комментарии:
1. Вау, я упустил это из виду в документации, большое спасибо! У меня было много подобных крайних случаев, и я не понимал, что иногда это требуется.