Skip to main content

处理滚动

许多应用程序都具有内容列表,从电子邮件客户端到音乐应用程序等等。要使用 widget 测试验证列表是否包含预期内容,您需要一种方法来滚动列表以搜索特定项目。

要通过集成测试滚动列表,请使用WidgetTester 类提供的 方法,该类包含在flutter_test 包中:

在本食谱中,学习如何滚动浏览项目列表以验证特定 widget 是否正在显示,以及不同方法的优缺点。

本食谱使用以下步骤:

  1. 创建一个包含项目列表的应用程序。
  2. 编写一个滚动浏览列表的测试。
  3. 运行测试。

1. 创建包含项目列表的应用程序

#

本食谱构建一个显示很长项目列表的应用程序。为了使本食谱专注于测试,请使用使用长列表 食谱中创建的应用程序。如果您不确定如何使用长列表,请参阅该食谱以获取介绍。

在集成测试中,为要与之交互的小部件添加键。

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

void main() {
  runApp(MyApp(
    items: List<String>.generate(10000, (i) => 'Item $i'),
  ));
}

class MyApp extends StatelessWidget {
  final List<String> items;

  const MyApp({super.key, required this.items});

  @override
  Widget build(BuildContext context) {
    const title = 'Long List';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: const Text(title),
        ),
        body: ListView.builder(
          // 向 ListView 添加一个键。这使得可以在测试中找到列表并滚动浏览它。
          key: const Key('long_list'),
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(
                items[index],
                // 为每个项目的 Text widget 添加一个键。这使得可以在列表中查找特定项目并验证文本是否正确。
                key: Key('item_${index}_text'),
              ),
            );
          },
        ),
      ),
    );
  }
}

2. 编写一个滚动浏览列表的测试

#

现在,您可以编写一个测试。在此示例中,滚动浏览项目列表并验证列表中是否存在特定项目。WidgetTester 类提供scrollUntilVisible() 方法,该方法滚动浏览列表直到特定 widget 可见。这很有用,因为列表中项目的⾼度可能会根据设备而变化。

与其假设您知道列表中所有项目的⾼度,或者特定 widget 在所有设备上都已渲染,不如使用 scrollUntilVisible() 方法重复滚动浏览项目列表,直到找到它要查找的内容。

以下代码显示了如何使用 scrollUntilVisible() 方法在列表中查找特定项目。此代码位于名为 test/widget_test.dart 的文件中。

dart

// 这是一个基本的 Flutter widget 测试。
//
// 要在测试中与 widget 交互,请使用 Flutter 提供的 WidgetTester 实用程序。例如,您可以发送点击和滚动手势。您还可以使用 WidgetTester 在 widget 树中查找子 widget、读取文本并验证 widget 属性的值是否正确。

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

import 'package:scrolling/main.dart';

void main() {
  testWidgets('finds a deep item in a long list', (tester) async {
    // 构建我们的应用程序并触发一个帧。
    await tester.pumpWidget(MyApp(
      items: List<String>.generate(10000, (i) => 'Item $i'),
    ));

    final listFinder = find.byType(Scrollable);
    final itemFinder = find.byKey(const ValueKey('item_50_text'));

    // 滚动直到要查找的项目出现。
    await tester.scrollUntilVisible(
      itemFinder,
      500.0,
      scrollable: listFinder,
    );

    // 验证项目是否包含正确的文本。
    expect(itemFinder, findsOneWidget);
  });
}

3. 运行测试

#

使用以下命令从项目的根目录运行测试:

flutter test test/widget_test.dart