Тесты виджета Flutter с разветвлением платформы

#flutter

#flutter

Вопрос:

В коде моего виджета мне нужно выполнить ветвление на Android / iOS, чтобы показывать виджеты, специфичные для каждой платформы, а также вызывать API, специфичные для платформы (например, виджет Android вызовет API, доступный только на Android).

   if (Platform.isAndroid) {
    return WidgetAndroid(...);
  } else if (Platform.isIOS) {
    return WidgetIOS(...);
  }
  

Как я могу проверить, отображается ли правильный виджет, используя тест виджета Flutter?

Я знаю, что могу проверить, существует ли виджет, но как мне запустить тест с определенной платформой.

 expect(find.byType(WidgetIOS), findsOneWidget);
  

Комментарии:

1. dev.to/arthurdenner/…

Ответ №1:

В 2022 году не рекомендуется использовать dart:io и Platform class для определения платформы выполнения. Лучшей альтернативой является использование, defaultTargetPlatform доступное через ‘package: flutter /foundation.dart’. Т.е.:

 if (defaultTargetPlatform == TargetPlatform.android ||
            defaultTargetPlatform == TargetPlatform.iOS) {}
  

Если у вас есть такой подход к определению платформы в вашем коде, переопределить платформу в тестах так же просто, как настроить debugDefaultTargetPlatformOverride в теле вашего теста.

https://api.flutter.dev/flutter/foundation/debugDefaultTargetPlatformOverride.html

Например.:

   testWidgets('DataTable2 renders with DataRow.index()',
      (WidgetTester tester) async {
    debugDefaultTargetPlatformOverride = TargetPlatform.android;
 ...
    debugDefaultTargetPlatformOverride = null;
  });
  

Ответ №2:

Оба Platform.isAndroid и Platform.isIOS возвращаются false при запуске testWidgets .

Некоторые предложения, которые мы можем применить в наших тестах:

  • Передайте платформу в качестве переменной вашему виджету верхнего уровня, таким образом, вы сможете ввести это значение вручную.
  • Укажите случай, когда вы хотите протестировать else без if , чтобы это выполнялось во время тестов.
  • Используйте вместо этого Platform из https://pub.dev/packages/platform что позволяет издеваться, что, вероятно, является лучшим долгосрочным решением.

Ответ №3:

Platform находится в dart:io , который находится на более низком уровне, чем у Flutter TargetPlatform . В большинстве случаев вам следует использовать последнее.

Из документации:

Объект [dart:io.Platform] следует использовать напрямую только тогда, когда действительно важно знать текущую платформу, без каких-либо возможных переопределений (например, когда готовится вызов системного API).

Ответ №4:

Как упоминал Мигель, вы не можете издеваться над ним напрямую.

Если вы используете платформу provider, вы можете использовать внедрение зависимостей в свои тесты, чтобы это произошло, не предоставляя дополнительных параметров в вашем виджете.

Создайте класс, который будет использоваться для внедрения:

 class PlatformInfo {
  final bool isIos;
  final bool isAndroid;

  PlatformInfo({@required this.isAndroid,@required  this.isIos});
}

  

в вашем виджете верхнего уровня MultiProvider настройте привязки вашего поставщика:

 Provider<PlatformInfo>.value(
    value: PlatformInfo(isAndroid: Platform.isAndroid, isIos: Platform.isIOS),
),
  

Используйте это в своем виджете:

 Provider.of<PlatformInfo>(context).isIos