集成测试

此页面介绍如何使用 integration_test 包来运行集成测试。使用此包编写的测试具有以下属性

  • flutter drive 命令兼容,用于在物理设备或模拟器上运行测试。
  • 可以在 Firebase Test Lab 上运行,从而在各种设备上进行自动化测试。
  • flutter_test API 兼容,使测试能够以类似于 小部件测试 的样式编写

概述

单元测试、小部件测试和集成测试

Flutter 支持三种类型的测试。单元测试验证方法或类的行为。小部件测试验证 Flutter 小部件的行为,而不运行应用本身。集成测试(也称为端到端测试或 GUI 测试)运行完整的应用。

主机和目标

在开发过程中,你可能在台式电脑(称为主机机器)上编写代码,并在移动设备、浏览器或台式机应用(称为目标设备)上运行应用。(如果你使用的是网络浏览器或台式机应用,则主机机器也是目标设备。)

integration_test

使用 integration_test 包编写的测试可以

  1. 直接在目标设备上运行,让你能够使用 Firebase Test Lab 在多个 Android 或 iOS 设备上进行测试。
  2. 使用 flutter test integration_test 运行。
  3. 使用 flutter_test API,使集成测试更像编写 小部件测试

从 flutter_driver 迁移

使用 flutter_driver 的现有项目可以通过遵循 从 flutter_drive 迁移指南迁移到 integration_test

项目设置

integration_testflutter_test 添加到你的 pubspec.yaml 文件

$ flutter pub add 'dev:flutter_test:{"sdk":"flutter"}'  'dev:integration_test:{"sdk":"flutter"}'
"flutter_test" is already in "dev_dependencies". Will try to update the constraint.
Resolving dependencies... 
  collection 1.17.2 (1.18.0 available)
+ file 6.1.4 (7.0.0 available)
+ flutter_driver 0.0.0 from sdk flutter
+ fuchsia_remote_debug_protocol 0.0.0 from sdk flutter
+ integration_test 0.0.0 from sdk flutter
  material_color_utilities 0.5.0 (0.8.0 available)
  meta 1.9.1 (1.10.0 available)
+ platform 3.1.0 (3.1.2 available)
+ process 4.2.4 (5.0.0 available)
  stack_trace 1.11.0 (1.11.1 available)
  stream_channel 2.1.1 (2.1.2 available)
+ sync_http 0.3.1
  test_api 0.6.0 (0.6.1 available)
+ vm_service 11.7.1 (11.10.0 available)
+ webdriver 3.0.2
Changed 9 dependencies!

在你的项目中,创建一个新目录 integration_test,其中包含一个新文件 <name>_test.dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:how_to/main.dart';
import 'package:integration_test/integration_test.dart';

void main() {
  testWidgets('tap on the floating action button, verify counter',
      (tester) async {
    // Load app widget.
    await tester.pumpWidget(const MyApp());

    // Verify the counter starts at 0.
    expect(find.text('0'), findsOneWidget);

    // Finds the floating action button to tap on.
    final fab = find.byKey(const Key('increment'));

    // Emulate a tap on the floating action button.
    await tester.tap(fab);

    // Trigger a frame.
    await tester.pumpAndSettle();

    // Verify the counter increments by 1.
    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
  });
}

如果你正在寻找更多示例,请查看 testing_appsamples 存储库。

目录结构

lib/
  ...
integration_test/
  foo_test.dart
  bar_test.dart
test/
  # Other unit tests go here.

另请参阅

使用 flutter 命令运行

这些测试可以使用 flutter test 命令启动,其中 <DEVICE_ID>:是 flutter devices 命令输出中显示的可选设备 ID 或模式

$ flutter test integration_test/foo_test.dart -d <DEVICE_ID>

这会在 foo_test.dart 中运行测试。要在默认设备上运行此目录中的所有测试,请运行

$ flutter test integration_test

在浏览器中运行

下载并安装 ChromeDriver,并在端口 4444 上运行它

$ chromedriver --port=4444

要使用 flutter drive 运行测试,请创建一个包含新文件 test_driver/integration_test.dart 的新目录

import 'package:integration_test/integration_test_driver.dart';

Future<void> main() => integrationDriver();

然后在你的 integration_test/<name>_test.dart 文件中添加 IntegrationTestWidgetsFlutterBinding.ensureInitialized()

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:how_to/main.dart';
import 'package:integration_test/integration_test.dart';

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized(); // NEW

  testWidgets('tap on the floating action button, verify counter',
      (tester) async {
    // Load app widget.
    await tester.pumpWidget(const MyApp());

    // Verify the counter starts at 0.
    expect(find.text('0'), findsOneWidget);

    // Finds the floating action button to tap on.
    final fab = find.byKey(const Key('increment'));

    // Emulate a tap on the floating action button.
    await tester.tap(fab);

    // Trigger a frame.
    await tester.pumpAndSettle();

    // Verify the counter increments by 1.
    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
  });
}

在单独的进程中,运行 flutter_drive

$ flutter drive \
   --driver=test_driver/integration_test.dart \
   --target=integration_test/counter_test.dart \
   -d web-server

要了解更多信息,请参阅 使用 Web 运行 Flutter 驱动程序测试 wiki 页面。

在 Firebase Test Lab 上进行测试

你可以将 Firebase Test Lab 与 Android 和 iOS 目标同时使用。

Android 设置

按照 README 中Android 设备测试部分中的说明进行操作。

iOS 设置

按照 README 中iOS 设备测试部分中的说明进行操作。

Test Lab 项目设置

前往Firebase 控制台,如果你还没有项目,请创建一个新项目。然后导航至质量与gt; 测试实验室

Firebase Test Lab Console

上传 Android APK

使用 Gradle 创建 APK

$ pushd android
# flutter build generates files in android/ for building the app
flutter build apk
./gradlew app:assembleAndroidTest
./gradlew app:assembleDebug -Ptarget=integration_test/<name>_test.dart
$ popd

其中 <name>_test.dart 是在项目设置部分中创建的文件。

将“debug”APK 从 <flutter_project_directory>/build/app/outputs/apk/debug 拖动到网页上的Android Robo 测试目标。这将启动 Robo 测试,并允许你运行其他测试

Firebase Test Lab upload

点击运行测试,选择Instrumentation 测试类型,并拖动以下两个文件

  • <flutter_project_directory>/build/app/outputs/apk/debug/<file>.apk
  • <flutter_project_directory>/build/app/outputs/apk/androidTest/debug/<file>.apk

Firebase Test Lab upload two APKs

如果发生故障,你可以通过选择红色图标来查看输出

Firebase Test Lab test results

从命令行上传 Android APK

请参阅 README 中的Firebase Test Lab 部分,了解如何从命令行上传 APK 的说明。

上传 Xcode 测试

有关如何将 .zip 文件上传到 Firebase 控制台的 Firebase TestLab 部分的详细信息,请参阅Firebase TestLab iOS 说明

从命令行上传 Xcode 测试

有关如何从命令行上传 .zip 文件的说明,请参阅自述文件中的iOS 设备测试部分。