DriverError:由于远程错误颤动,未能完成 Tap

Posted

技术标签:

【中文标题】DriverError:由于远程错误颤动,未能完成 Tap【英文标题】:DriverError: Failed to fulfill Tap due to remote error flutter 【发布时间】:2019-11-22 14:02:36 【问题描述】:

我有一些自定义的 TextFiels,它们用于输入 pin,我称它们为 PinInputField。当我使用颤振驱动器运行集成测试时,所有输入字段都将收到给定的文本,除了最后一个并停止运行测试。 这是代码: 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)

【问题讨论】:

你能分享包括PinInputField的完整代码吗? 【参考方案1】:

此问题主要发生在测试在实际完成之前超时。用于运行测试的默认超时时间为 30 秒,这里您的睡眠持续时间加起来超过 30 秒,因此连接因未决请求而关闭。

我不明白为什么每次动作后要睡一段时间,可能是你可以减少/消除睡眠。如果您的情况需要睡眠,请尝试通过适当的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),
  ),
);

希望有帮助!

【讨论】:

【参考方案2】:

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

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

注意: 实施timeoutclearTimeline() 可以完成运行时间较长的测试。但我建议无论大小如何都添加到每个测试中。我最初也尝试过sleeps,并在使用timeoutclearTimeline() 后将它们全部删除。

希望这会有所帮助。

【讨论】:

【参考方案3】:

我希望我的发现能够对某人有所帮助。

我收到错误“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);
    );
  );

【讨论】:

以上是关于DriverError:由于远程错误颤动,未能完成 Tap的主要内容,如果未能解决你的问题,请参考以下文章

无法加载 providerinstaller 模块:找不到可接受的模块。本地版本为 0 远程版本为 0 错误颤动

vs2012 Nuget错误:“未能解析此远程名称api.nuget.org”

多多云手机提示未能解析此远程名称啥意思

关于finder不能完成该操作 因为未能读取或写入"文件名"中的某些数据(错误代码-36)(实测,好用)

RuntimeError:由于Windows运行时中的错误,当前的Numpy安装未能通过完整性检查[重复]

权限处理程序颤动多个权限错误