Flutter 小部件测试点击 - 不会在指定的小部件上进行测试

Posted

技术标签:

【中文标题】Flutter 小部件测试点击 - 不会在指定的小部件上进行测试【英文标题】:Flutter widget test tap - would not hit test on the specified widget 【发布时间】:2021-09-22 17:28:32 【问题描述】:

输出以下警告后,我的小部件测试失败:

flutter:警告:使用 finder 调用 tap()“恰好是一个带有文本“Tab 2”的小部件(忽略后台小部件):Text(“Tab 2”,softWrap:除了换行符之外没有换行,溢出: fade, dependencies: [MediaQuery, DefaultTextStyle])" 派生了一个偏移量 (Offset(600.0, 23.0)),它不会在指定的小部件上进行测试。 flutter: 可能小部件实际上不在屏幕上,或者另一个小部件遮挡了它,或者小部件无法接收指针事件。

tap 永远不会执行,因此下一部分测试失败。我在测试中放了一些延迟,似乎测试正在尝试点击正确的小部件 - 它没有在屏幕外,没有被遮挡,并且过去能够接收指针事件 - 不确定它为什么目前失败。

这是一个最小的可重现示例:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: TabBar(
            labelColor: Color(0xff8391e4),
            tabs: [
              Tab(text: 'Tab 1'),
              Tab(text: 'Tab 2'),
            ],
          ),
          body: TabBarView(
            children: <Widget>[
              Text('Tab 1 Text'),
              Text('Tab 2 Text'),
            ],
          ),
        ),
      ),
    );
  


void main() 
  TestWidgetsFlutterBinding.ensureInitialized();

  testWidgets('My Test', (WidgetTester tester) async 
    await tester.pumpWidget(MyApp());
    await tester.pumpAndSettle();

    // Warning thrown on this tap - tap never executed
    await tester.tap(find.text('Tab 2'));
    await tester.pumpAndSettle();

    // Test fails here
    expect(find.text('Tab 2 Text'), findsOneWidget);
  );

【问题讨论】:

我遇到了同样的问题,您找到解决方案了吗?我也试过ensureVisible。没有运气。 @LeeMordell 有这方面的消息吗?你找到解决办法了吗? @Dirk - 有一段时间没有测试过,很遗憾没有解决方案。 :( 【参考方案1】:

尝试在tap()之前设置ensureVisible()

// Warning thrown on this tap - tap never executed
await tester.ensureVisible(find.text('Tab 2'));
await tester.tap(find.text('Tab 2'));
await tester.pumpAndSettle();

【讨论】:

感谢您的建议。 ensureVisible 非常适合当小部件不在屏幕上并且您想滚动到它时;但是,在我的情况下,小部件在屏幕上清晰可见。 我目前遇到了同样的问题@LeeMordell,但是当我在模拟器上运行测试时,正如您在评论中提到的那样,它是可见的。您是否设法找到解决此问题的方法? ensureVisible 不是关于在真实模拟器中不可见,而是关于此特定组件在测试模拟器的屏幕上可见。因此,它会在模拟器屏幕上模拟滚动,直到相关组件可见【参考方案2】:

我找到了解决问题的方法,但它可能不是通用的解决方案。此测试所针对的应用程序是专门的网络应用程序,因此它旨在在更大的屏幕尺寸上运行。当我在 chrome 上运行测试时它会通过,但如果不小心运行就会失败。

为了解决这个问题,我在更大的屏幕尺寸下运行测试,现在它不经意地通过了。 因此,如果您遇到A call to tap() ... that would not hit test on the specified widget 错误,调整屏幕大小可能会解决问题。

  testWidgets('My test', (WidgetTester tester) async 
      // Here we use physicalSizeTestValue to adjust the test screen size to
      // simulate running on a desktop computer which the app was designed for
      tester.binding.window.physicalSizeTestValue = Size(1080, 1920);
      tester.binding.window.devicePixelRatioTestValue = 1.0;

【讨论】:

以上是关于Flutter 小部件测试点击 - 不会在指定的小部件上进行测试的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 测试中查找 CustomScrollView 内的小部件

Flutter ListView 与 List 中的小部件不会在应该更新时更新

Flutter 不会使用不同的参数重建相同的小部件

Flutter 可拖动的小部件,可以单击或拖动以移动到 DragTarget

三元条件没有重建我的小部件 - Flutter

如何对访问 Provider.of(context) 的小部件进行 Flutter 测试