DriverError: Failed to fulfill Tap due to remote error flutter

DriverError: Failed to fulfill Tap due to remote error flutter

我有一些自定义的 TextFiels,它们用于输入 PIN,我将它们命名为 PinInputField。当我 运行 使用 flutter drive 进行集成测试时,所有输入字段都将收到给定的文本,最后一个除外并停止 运行 测试。 这是代码: P.s:我正在使用 HookWidget

    final focusNodes = List.generate(6, (_) => new FocusNode());
    final values = List.generate(6, (_) => useState<String>(''));

Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    for (int i = 0; i < values.length; i++)
                      PinInputField(
                        key: ValueKey('$i'),
                        width: MediaQuery.of(context).size.width / 11.71,
                        height: 80,
                        fontSize: 50,
                        marginRight: 16,
                        input: values[i],
                        focusNode: focusNodes[i],
                        nextFocusNode: i == 5 ? null : focusNodes[i + 1],
                      )
                  ],
                )

这是测试:

    test('test main card settings items', () async {
      final cardSettingsItem = find.byValueKey('settings.cardSettings');
       final mainSettingsList = find.byValueKey('mainSettingsList');
      final profileButton = find.byValueKey('Profile');
      final changePinButton = find.byValueKey('Cambiar pin');
      final changePinInputField0 = find.byValueKey('0');
      final changePinInputField1 = find.byValueKey('1');
      final changePinInputField2 = find.byValueKey('2');
      final changePinInputField3 = find.byValueKey('3');
      final changePinInputField4 = find.byValueKey('4');
      final changePinInputField5 = find.byValueKey('5');
      final changePinScreenButton = find.byValueKey('changePinScreenButton');
      sleep(Duration(seconds: 3));
      await driver.tap(profileButton);
      sleep(Duration(seconds: 2));
      await driver.scrollIntoView(mainSettingsList);
      sleep(Duration(seconds: 3));
      await driver.tap(cardSettingsItem);
      sleep(Duration(seconds: 3));
      await driver.tap(changePinButton);
      sleep(Duration(seconds: 4));
      await driver.tap(changePinInputField0);
      sleep(Duration(seconds: 2));
      await driver.enterText("0");
      sleep(Duration(seconds: 1));
      await driver.tap(changePinInputField1);
      sleep(Duration(seconds: 2));
      await driver.enterText("1");
      sleep(Duration(seconds: 1));
      await driver.tap(changePinInputField2);
      sleep(Duration(seconds: 2));
      await driver.enterText("2");
      sleep(Duration(seconds: 1));
      await driver.tap(changePinInputField3);
      sleep(Duration(seconds: 2));
      await driver.enterText("3");
      sleep(Duration(seconds: 1));
      await driver.tap(changePinInputField4);
      sleep(Duration(seconds: 2));
      await driver.enterText("4");
      sleep(Duration(seconds: 4));
      await driver.tap(changePinInputField5);
      sleep(Duration(seconds: 1));
      await driver.enterText("5");
      sleep(Duration(seconds: 5));
      await driver.tap(changePinScreenButton);
      sleep(Duration(seconds: 4));
    });

这是日志:

 DriverError: Failed to fulfill Tap due to remote error
  Original error: Bad state: The client closed with pending request "ext.flutter.driver".
  Original stack trace:
  #0      new Client.withoutJson.<anonymous closure> (package:json_rpc_2/src/client.dart:70:24)
  #1      StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
  #2      StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
  #3      _rootRun (dart:async/zone.dart:1120:38)
  #4      _CustomZone.run (dart:async/zone.dart:1021:19)
  #5      _FutureListener.handleWhenComplete (dart:async/future_impl.dart:150:18)
  #6      Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:609:39)
  #7      Future._propagateToListeners (dart:async/future_impl.dart:665:37)
  #8      Future._propagateToListeners (dart:async/future_impl.dart:566:9)
  #9      Future._completeWithValue (dart:async/future_impl.dart:483:5)
  #10     Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:513:7)
  #11     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
  #12     StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
  #13     _rootRun (dart:async/zone.dart:1124:13)
  #14     _CustomZone.run (dart:async/zone.dart:1021:19)
  #15     _CustomZone.runGuarded (dart:async/zone.dart:923:7)
  #16     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:963:23)
  #17     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
  #18     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
  #19     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:391:30)
  #20     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
  #21     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)

这个问题主要发生在测试未真正完成就超时的情况下。用于 运行 测试的默认超时为 30 秒,此处您的睡眠持续时间加起来超过 30 秒,因此连接因未决请求而关闭。

我不明白为什么每次动作后都要睡一段时间,也许你可以reduce/remove睡觉。如果睡眠对于您的情况是强制性的,请尝试将适当的 timeout 传递给测试。

示例:

test(
  'test main card settings items',
  () async {
    final cardSettingsItem = find.byValueKey('settings.cardSettings');
    final mainSettingsList = find.byValueKey('mainSettingsList');
    final profileButton = find.byValueKey('Profile');
    final changePinButton = find.byValueKey('Cambiar pin');
    final changePinInputField0 = find.byValueKey('0');
    final changePinInputField1 = find.byValueKey('1');
    final changePinInputField2 = find.byValueKey('2');
    final changePinInputField3 = find.byValueKey('3');
    final changePinInputField4 = find.byValueKey('4');
    final changePinInputField5 = find.byValueKey('5');
    final changePinScreenButton = find.byValueKey('changePinScreenButton');
    sleep(Duration(seconds: 3));
    await driver.tap(profileButton);
    sleep(Duration(seconds: 2));
    await driver.scrollIntoView(mainSettingsList);
    sleep(Duration(seconds: 3));
    await driver.tap(cardSettingsItem);
    sleep(Duration(seconds: 3));
    await driver.tap(changePinButton);
    sleep(Duration(seconds: 4));
    await driver.tap(changePinInputField0);
    sleep(Duration(seconds: 2));
    await driver.enterText("0");
    sleep(Duration(seconds: 1));
    await driver.tap(changePinInputField1);
    sleep(Duration(seconds: 2));
    await driver.enterText("1");
    sleep(Duration(seconds: 1));
    await driver.tap(changePinInputField2);
    sleep(Duration(seconds: 2));
    await driver.enterText("2");
    sleep(Duration(seconds: 1));
    await driver.tap(changePinInputField3);
    sleep(Duration(seconds: 2));
    await driver.enterText("3");
    sleep(Duration(seconds: 1));
    await driver.tap(changePinInputField4);
    sleep(Duration(seconds: 2));
    await driver.enterText("4");
    sleep(Duration(seconds: 4));
    await driver.tap(changePinInputField5);
    sleep(Duration(seconds: 1));
    await driver.enterText("5");
    sleep(Duration(seconds: 5));
    await driver.tap(changePinScreenButton);
    sleep(Duration(seconds: 4));
  },
  timeout: Timeout(
    Duration(minutes: 2),
  ),
);

希望对您有所帮助!

我也一直在为默认的 30 秒超时设置而苦恼。只有当 Flutter Driver 测试在远程 CI/CD 上 运行 时才会出现问题。本地测试 运行 很棒。我做了两件事似乎适用于远程 CI/CD:

  1. 指定了上面规定的 timeout @Hemanth。谢谢@Hemanth!
  2. 在每个测试开始时添加 clearTimeline()
   test('Home page should properly work', () async {
      await driver.clearTimeline();
      await HomePage(driver).appears()
          .then((a) => a.exploreHomePage());
    },
      timeout: Timeout(
        Duration(minutes: 2),
      ),
    );

注意: 实施 timeout & clearTimeline() 允许完成更长的 运行ning 测试。但我建议无论大小如何都添加到每个测试中。我最初也尝试过 sleeps,并最终在使用 timeout & clearTimeline().

后将它们全部删除

希望这对您有所帮助。

我希望我的发现能够帮助到别人。

我收到错误“DriverError:由于远程错误无法实现 Tap”和“VMServiceFlutterDriver:tap 消息需要很长时间才能完成。”

就我而言,Flutter Driver 无法找到要测试的小部件,因为我使用的是 'find.byType'。有一次,我为所有小部件提供了密钥,并传递给使用 'find.byValueKey',小部件已本地化并且一切正常。

那是我的代码:

void main() {
  group('reversor app integration test', () {
    FlutterDriver driver;

    setUpAll(() async {
      driver = await FlutterDriver.connect();
    });

    tearDownAll(() {
      if (driver != null) {
        driver.close();
      }
    });

    // find.byType was the cause for the error 'DriverError: Failed to fulfill Tap due to remote error'
    // Given key for the three below widgets, and after hat using 'find.byValueKey', solved the problem
    var field = find.byValueKey("TextField");
    var btn = find.byValueKey("button");
    var reverse = find.byValueKey("response");

    test('Reversing the string', () async {
      await driver.clearTimeline();
      await driver.tap(field);
      await driver.enterText("Hello222");
      await driver.waitForAbsent(reverse);
      await driver.tap(btn);
      await driver.waitFor(reverse);
      await driver.waitUntilNoTransientCallbacks();
      assert(reverse != null);
    });
  });
}