本页面介绍了如何将使用 flutter_driver 的现有项目迁移到 integration_test 包,以便运行集成测试。

使用 integration_test 的测试采用了 小组件测试 中使用的方法。

有关 integration_test 包的介绍,请参阅 集成测试 指南。

启动示例项目

#

本指南中的项目是一个小型桌面示例应用程序,具有以下功能

  • 在左侧,有一个植物列表,用户可以滚动、点击和选择。
  • 在右侧,有一个详细信息屏幕,显示植物的名称和物种。
  • 应用程序启动时,如果没有选择植物,将显示一段文本,要求用户选择一种植物。
  • 植物列表从位于 /assets 文件夹中的本地 JSON 文件加载。
Starter project screenshot

你可以在 示例项目 文件夹中找到完整的代码示例。

现有测试

#

该项目包含三个 flutter_driver 测试,执行以下检查:

  • 验证应用程序的初始状态。
  • 选择植物列表中的第一个项目。
  • 滚动并选择植物列表中的最后一个项目。

测试包含在 test_driver 文件夹中的 main_test.dart 文件内。

此文件夹中还有一个名为 main.dart 的文件,其中包含对 enableFlutterDriverExtension() 方法的调用。使用 integration_test 后,此文件将不再需要。

设置

#

要开始使用 integration_test 包,如果尚未添加,请将 integration_test 添加到你的 pubspec.yaml 文件中。

yaml
dev_dependencies:
  integration_test:
    sdk: flutter

接下来,在你的项目中,创建一个新目录 integration_test/,并在其中创建你的测试文件,格式为:<name>_test.dart

测试迁移

#

本节包含将现有 flutter_driver 测试迁移到 integration_test 测试的不同示例。

示例:验证小组件是否显示

#

应用程序启动时,右侧屏幕会显示一段文本,要求用户选择列表中的一种植物。

此测试验证该文本是否显示。

flutter_driver

flutter_driver 中,测试使用 waitFor,它会等待 finder 找到小组件。如果找不到小组件,测试将失败。

dart
test(
  'do not select any item, verify please select text is displayed',
  () async {
    // Wait for 'please select' text is displayed
    await driver.waitFor(find.text('Please select a plant from the list.'));
  },
);

integration_test

integration_test 中,你需要执行两个步骤:

  1. 首先,使用 tester.pumpWidget 方法加载主应用程序小组件。

  2. 然后,使用 expect 和匹配器 findsOneWidget 来验证小组件是否显示。

dart
testWidgets(
  'do not select any item, verify please select text is displayed',
  (tester) async {
    // load the PlantsApp widget
    await tester.pumpWidget(const PlantsApp());

    // wait for data to load
    await tester.pumpAndSettle();

    // Find widget with 'please select'
    final finder = find.text('Please select a plant from the list.');

    // Check if widget is displayed
    expect(finder, findsOneWidget);
  },
);

示例:点击操作

#

此测试对列表中的第一个项目(一个带有文本“Alder”的 ListTile)执行点击操作。

点击后,测试等待详细信息出现。在这种情况下,它等待显示带有文本“Alnus”的小组件。

此外,测试验证文本“请从列表中选择一种植物。”不再显示。

flutter_driver

flutter_driver 中,使用 driver.tap 方法通过 finder 对小组件执行点击操作。

要验证小组件是否未显示,请使用 waitForAbsent 方法。

dart
test('tap on the first item (Alder), verify selected', () async {
  // find the item by text
  final item = find.text('Alder');

  // Wait for the list item to appear.
  await driver.waitFor(item);

  // Emulate a tap on the tile item.
  await driver.tap(item);

  // Wait for species name to be displayed
  await driver.waitFor(find.text('Alnus'));

  // 'please select' text should not be displayed
  await driver.waitForAbsent(
    find.text('Please select a plant from the list.'),
  );
});

integration_test

integration_test 中,使用 tester.tap 执行点击操作。

点击操作后,你必须调用 tester.pumpAndSettle 来等待操作完成,并且所有 UI 更改都已发生。

要验证小组件是否未显示,请使用与 findsNothing 匹配器相同的 expect 函数。

dart
testWidgets('tap on the first item (Alder), verify selected', (tester) async {
  await tester.pumpWidget(const PlantsApp());

  // wait for data to load
  await tester.pumpAndSettle();

  // find the item by text
  final item = find.text('Alder');

  // assert item is found
  expect(item, findsOneWidget);

  // Emulate a tap on the tile item.
  await tester.tap(item);
  await tester.pumpAndSettle();

  // Species name should be displayed
  expect(find.text('Alnus'), findsOneWidget);

  // 'please select' text should not be displayed
  expect(find.text('Please select a plant from the list.'), findsNothing);
});

示例:滚动

#

此测试与之前的测试类似,但它向下滚动并点击最后一个项目。

flutter_driver

要使用 flutter_driver 向下滚动,请使用 driver.scroll 方法。

你必须提供执行滚动操作的小组件,以及滚动的持续时间。

你还需要提供滚动操作的总偏移量。

dart
test('scroll, tap on the last item (Zedoary), verify selected', () async {
  // find the list of plants, by Key
  final listFinder = find.byValueKey('listOfPlants');

  // Scroll to the last position of the list
  // a -100,000 pixels is enough to reach the bottom of the list
  await driver.scroll(
    listFinder,
    0,
    -100000,
    const Duration(milliseconds: 500),
  );

  // find the item by text
  final item = find.text('Zedoary');

  // Wait for the list item to appear.
  await driver.waitFor(item);

  // Emulate a tap on the tile item.
  await driver.tap(item);

  // Wait for species name to be displayed
  await driver.waitFor(find.text('Curcuma zedoaria'));

  // 'please select' text should not be displayed
  await driver.waitForAbsent(
    find.text('Please select a plant from the list.'),
  );
});

integration_test

使用 integration_test,可以使用 tester.scrollUntilVisible 方法。

你无需提供要滚动的小组件,而是提供你正在查找的项目。在这种情况下,你正在查找带有文本“Zedoary”的项目,它是列表中的最后一个项目。

该方法会搜索任何 Scrollable 小组件,并使用给定的偏移量执行滚动操作。此操作会重复进行,直到项目可见。

dart
testWidgets('scroll, tap on the last item (Zedoary), verify selected', (
  tester,
) async {
  await tester.pumpWidget(const PlantsApp());

  // wait for data to load
  await tester.pumpAndSettle();

  // find the item by text
  final item = find.text('Zedoary');

  // finds Scrollable widget and scrolls until item is visible
  // a 100,000 pixels is enough to reach the bottom of the list
  await tester.scrollUntilVisible(item, 100000);

  // assert item is found
  expect(item, findsOneWidget);

  // Emulate a tap on the tile item.
  await tester.tap(item);
  await tester.pumpAndSettle();

  // Wait for species name to be displayed
  expect(find.text('Curcuma zedoaria'), findsOneWidget);

  // 'please select' text should not be displayed
  expect(find.text('Please select a plant from the list.'), findsNothing);
});