#dart #flutter #flutter-test
#dart #флаттер #тест на флаттер
Вопрос:
как мне протестировать BottomNavigationBarItems с помощью FlutterDriver?
FlutterDriver позволяет получать доступ к виджетам через text, byValueKey, byTooltip и byType.
Но ни один из этих методов не работает для моего приложения по следующим причинам:
-
текст: Приложение локализовано, и мне нужно протестировать приложение на нескольких языках.
-
byValueKey: у BottomNavigationBarItems нет свойств ключа.
-
byTooltip: у BottomNavigationBarItems нет свойств всплывающей подсказки.
-
byType: byType возвращает только первое совпадение типа и не содержит списка (необходим, потому что у меня есть несколько вкладок).
Большое вам спасибо!
Приветствия.
Ответ №1:
Не уверен, нашли ли вы ответ на этот вопрос, но я собираюсь опубликовать здесь решение, которое работает для меня. В принципе, BottomNavigationBar
имеет key
свойство, которое вам нужно использовать. Как только драйвер Flutter идентифицирует этот ключ, вы можете указать драйверу нажать на любой из его дочерних элементов, т.Е. BottomNavigationBarItem
.
На моем экране есть 2, bottomNavigationBarItems
как показано ниже, и я определил ключ для их родительского виджета, т.Е. BottomNavigationBar
как:
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.shifting,
key: Key('bottom'),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit, color: Colors.green,),
title: Text('First', style: TextStyle(color: Colors.black),)
),
BottomNavigationBarItem(
icon: Icon(Icons.cast, color: Colors.yellow,),
title: Text('Second', style: TextStyle(color: Colors.black),)
)
],
),
И я написал тест драйвера флаттера, чтобы коснуться обоих элементов, которые отлично сработали.
test('bottomnavigationbar test', () async {
await driver.waitFor(find.byValueKey('bottom'));
await driver.tap(find.text('First'));
print('clicked on first');
await driver.tap(find.text('Second'));
print('clicked on second too');
});
Результат:
Комментарии:
1. Спасибо за ваш ответ. Ваше решение работает, но, к сожалению, не для меня. Мое приложение локализовано и, следовательно, имеет разные тексты в зависимости от вашего языка.
2. @basedgod разве мы не можем использовать key в текстовом виджете? « BottomNavigationBarItem ( значок: Icon ( Icons.settings), заголовок: Текст ( ‘Настройки’, клавиша: const Key (‘настройки’), ),`» кажется, у меня это работает.
3. Да, как и в bsr, у меня сработало наложение клавиши на значок.
4. Похоже, что
flutter_driver
это больше не рекомендуемый способ: docs.flutter.dev/testing/integration-tests/migration
Ответ №2:
Как упоминалось @bsr и @user12563357 — вы можете использовать клавишу для текстового виджета:
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.shifting,
key: Key('bottom'),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
title: Text('First', key: Key('first'),)
),
BottomNavigationBarItem(
icon: Icon(Icons.cast),
title: Text('Second', key: Key('second'),)
)
],
),
и найдите текст, чтобы щелкнуть по элементу панели в test:
final firstItem = find.byValueKey('first');
await driver.tap(firstItem);
кстати: вы также можете найти BottomNavigationBarItem с помощью find.ancestor
find.ancestor(of: firstItem, matching: find.byType("BottomNavigationBarItem"));
но вы не можете нажать на него.
Комментарии:
1. Сработает ли установка клавиши на значок?
Ответ №3:
У вас есть два варианта — с помощью значка или с текстом, получая локализацию из контекста.
Вы можете получить состояние любого вида StatefulWidget.
final MyWidgetState state = tester.state(find.byType(MyWidget));
с помощью этого вы можете получить контекст, а с ним и текущую локализацию.
final l10n = AppLocalizations.of(state.context);
await tester.tap(find.text(l10n.youTitle));
Еще один вариант — получить виджет по значку:
await tester.tap(find.byIcon(Icons.your_icon));
Ответ №4:
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.shifting,
key: Key(`bottom`),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit, color: Colors.green,),
title: InkWell(child:Text(`First`, style: TextStyle(color: Colors.black),key:Key(`First`)),)
),
BottomNavigationBarItem(
icon: Icon(Icons.cast, color: Colors.yellow,),
title: InkWell(child:Text(`Second`, style: TextStyle(color: Colors.black),key:Key(`Second`)),)
)
],
),
test(`bottomnavigationbar test`, () async {
await driver.waitFor(find.byValueKey(`bottom`));
await driver.tap(find.byValueKey(`First`));
print('clicked on first');
await driver.tap(find.byValueKey(`Second`));
print('clicked on second too');
});
Комментарии:
1. Спасибо за ваш ответ, но, пожалуйста, объясните код и как / почему это работает. Просто с помощью кода трудно понять ответ.
2. Добавьте виджет «InkWell» в качестве заголовка для BottomNavigationBarItem и добавьте текст в качестве дочернего элемента для InkWell. Теперь у вас может быть статический английский ключ для виджета InkWell, который не нужно менять в зависимости от локали, и после этого с помощью api «driver.tap (find.byValueKey(‘key’))» вы можете реализовать функциональность BottomNavigationBarItem ontap.