Тест на флаттер работает только с длительностью откачки

#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. Вау, я упустил это из виду в документации, большое спасибо! У меня было много подобных крайних случаев, и я не понимал, что иногда это требуется.