1

我正在尝试编写一些从登录尝试开始的集成测试,然后继续将应用程序导航到某个页面。登录尝试实际上成功了,但在那之后我尝试查找任何小部件失败了,所以我无法进一步导航。

登录页面后,应用程序会自动正确导航到应用程序中的下一页,但是我的测试脚本在该页面上找不到任何小部件,即使我可以在屏幕上的 android 模拟器中看到它们。

我的 app_test.dat 文件如下所示:

 
import ...

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
  
  group('sign in : ', () {
    testWidgets('try to SIGN IN and  open the menu ',
        (WidgetTester tester) async {
      app.main();
      await tester.pumpAndSettle(const Duration(milliseconds: 5000));
      await tester.pumpAndSettle();

      expect(find.text('SIGN IN', skipOffstage: false), findsWidgets);

      expect(find.byKey(Key('loginPagePasswordField')), findsOneWidget);
      expect(find.byKey(Key('loginPageEmailField')), findsOneWidget);
      print('found fields');
      await tester.enterText(
          find.byKey(Key('loginPageEmailField')), 'myname@here.com');
      await tester.enterText(
          find.byKey(Key('loginPagePasswordField')), 'myname123zxc');
      print('entered text');
      await tester.testTextInput.receiveAction(TextInputAction.done);
      await tester.pump();
      print('entered DONE');
 
      await tester.pumpAndSettle(const Duration(milliseconds: 5000));
      await tester.pumpAndSettle();


      // Now try to find the menu icon button
      var x = find.byTooltip('Open navigation menu'); 
      expect(x, findsOneWidget);  // this fails but is needed to navigate the app
      print('find tab1 ');
      // Now try to find the 'ASD' Tab 
      final tabFinder = find.text('ASD', skipOffstage: false);
      expect(tabFinder, findsWidgets); // this also fails
  
    });
 
  });
}

和我的 f 医生(我使用 fvm):

[✓] Flutter (Channel stable, 2.8.0, on macOS 12.1 21C52 darwin-arm, locale en-CA)
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] VS Code (version 1.63.0)
[✓] Connected device (2 available)

• No issues found!
4

2 回答 2

1

在这种特殊情况下未找到小部件的可能原因有多种:

  1. 它不在屏幕上(完全或滚动出屏幕)
  2. 此处或实际代码中的工具提示不正确。
  3. 您尝试查找的小部件不是Tooltip小部件。
  4. 泵送时间太短。
  5. 也许一些模拟器特定的东西。

现在有什么可能的修复。

  1. 如果小部件在屏幕上并且对您可见并不意味着它对测试驱动程序可见 - 根据我的经验,这是一种非常常见的情况。您可以尝试使用tester.ensureVisible以确保它可见。或者实际滚动内容以确保使用tester.fling,tester.scrollUntilVisible或可以看到它tester.dragUntilVisible

  2. 检查你的工具提示字符串。我建议您不要以findByTooltip这种方式使用 - 您可能不知道设备的 excat 语言环境,如果应用程序启用了本地化 - 查找器将失败。如果您完全确定应用程序中不会有本地化 - 创建一个带有工具提示的静态字符串并在代码和测试中使用它 - 这样您就可以确保字符串是相同的。使用本地化 -在实现和测试中使用InheritedWidget方法并从上下文中检索字符串。appLocalizations.of(context)但这里的实际命题是根本不用findByTooltipfindByKey更可靠,因为它独立于上下文语言环境和手动输入错误 - 只需按照我之前的建议使用 Keys - 创建静态 consts 键并在代码和测试中使用相同的 const。

  3. 检查message您的字段Tooltip是否已填写并且与您尝试查找的字段相同。

  4. 多抽一点——也许会有所帮助。还尝试使用pump较长的持续时间,然后pumpAndSettle直接使用默认持续时间 - 有时它会有所帮助。

  5. 尝试在真实设备上运行测试。

您的问题的一般答案是,如果所有内容都正确编码并且屏幕上有这样的小部件,则 finder 会找到小部件。但我理解它为什么会出现问题——我已经编写了数千行 Flutter 集成测试,并且我看到了各种人为错误(包括我的)、奇怪的驱动程序/测试人员/查找器行为和设备/操作系统/框架特定情况。

于 2021-12-24T11:04:26.453 回答
0

似乎诀窍在于,在运行集成测试时,AppBar 的默认“前导”小部件或默认前导小部件的默认工具提示不存在。当应用程序在模拟器中以调试模式运行时,它就在那里 - 可以通过 debug-watch on 找到它MaterialLocalizations.of(context).openAppDrawerTooltip。当我在测试文件上运行调试时,该手表找不到工具提示 - 然后在这种情况下似乎没有手表可以工作。

修复方法是手动将“领先”小部件添加到 AppBar 中,如下所示:

appBar: AppBar(
              title: "my title",
              leading: Builder(
                builder: (BuildContext context) {
                  return IconButton(
                    icon: Icon(Icons.menu),
                    onPressed: () {
                      Scaffold.of(context).openDrawer();
                    },
                    tooltip: 'Open navigation menu',
                  );
                },
              ),
...

现在,进入下一个问题——为什么组中的下一个测试找不到任何小部件?

于 2022-01-05T14:49:22.600 回答