平台分支的颤动小部件测试



在我的小部件的代码中,我需要在Android/ios上分支以显示针对每个平台的窗口小部件,并调用特定于平台的API(例如,Android Widget只能在Android上拨打API)。

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

如何使用Flutter小部件测试测试正确的小部件?

我知道我可以检查小部件是否存在,但是如何使用特定平台进行测试。

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

在2022年不建议使用dart:ioPlatform类来确定运行时平台。更好的替代方法是使用defaultTargetPlatform通过"包装:Flutter/Foundation.dart"可用。即:

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

您是否有该方法在测试中的代码中确定平台中的平台就像在测试主体中设置debugDefaultTargetPlatformOverride一样容易。

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

例如:

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

运行testWidgetsPlatform.isAndroidPlatform.isIOS返回false

我们可以在测试中应用一些建议:

  • 将平台作为变量传递到您的顶级小部件,这样您就可以手动提供该值。
  • 使您想在没有if的情况下测试else,因此可以在测试期间运行。
  • 从https://pub.dev/packages/platform使用Platform,允许模拟,这可能是最佳的长期解决方案。

Platformdart:io中,比Flutter的TargetPlatform低级别。在大多数情况下,您应该使用后者。

来自文档:

[DART:io.platform]对象仅在实际了解当前平台至关重要的情况下直接使用,而无需任何可能的替代(例如,当要调用系统API时)。

像米格尔(Miguel)提到的那样,你不能直接模拟它。

如果您使用提供商框架,则可以在测试中使用依赖项注入来实现此目标,而不会在小部件中公开其他参数。

创建一个用于注入的类:

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