Skip to main content

使用集成测试检查应用功能

本教程描述如何使用integration_test 包运行集成测试。Flutter SDK 包含 integration_test 包。使用此包的集成测试具有以下特性:

  • 使用 flutter drive 命令在物理设备或模拟器上运行测试。
  • Firebase Test Lab 上运行,以便在各种设备上自动化测试。
  • 使用flutter_test API 允许以类似于组件测试 的风格编写测试。

在本教程中,学习如何测试计数器应用:

  • 如何设置集成测试
  • 如何验证应用是否显示特定文本
  • 如何点击特定组件
  • 如何运行集成测试

本教程使用以下步骤:

  1. 创建一个要测试的应用。
  2. 添加 integration_test 依赖项。
  3. 创建测试文件。
  4. 编写集成测试。
  5. 运行集成测试。

创建一个新的应用进行测试

#

集成测试需要一个要测试的应用。本示例使用 Flutter 运行 flutter create 命令时生成的内置 计数器应用 示例。计数器应用允许用户点击按钮来增加计数器。

  1. 要创建一个内置 Flutter 应用的实例,请在终端中运行以下命令:

    flutter create counter_app
  2. 进入 counter_app 目录。

  3. 在你喜欢的 IDE 中打开 lib/main.dart

  4. 使用带有 'increment' 字符串值的 Key 类实例,向 floatingActionButton() 组件添加 key 参数。

    dart
     floatingActionButton: FloatingActionButton(
       key: const ValueKey('increment'),
       onPressed: _incrementCounter,
       tooltip: 'Increment',
       child: const Icon(Icons.add),
     ),
  5. 保存你的 lib/main.dart 文件。

进行这些更改后,lib/main.dart 文件应类似于以下代码:

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

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Counter App',
      home: MyHomePage(title: 'Counter App Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        // 为此按钮提供一个 Key。这允许在测试套件中找到此特定按钮并点击它。
        key: const Key('increment'),
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

添加 integration_test 依赖项

#

你需要将测试包添加到你的新应用中。

要使用 sdk: flutterintegration_testflutter_test 包添加为 dev_dependencies,请运行以下命令:

flutter pub add 'dev:integration_test:{"sdk":"flutter"}'

输出:

Building flutter tool...
Resolving dependencies... 
Got dependencies.
Resolving dependencies... 
+ file 7.0.0
+ 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
...
  test_api 0.6.1 (0.7.1 available)
  vm_service 13.0.0 (14.2.1 available)
+ webdriver 3.0.3
Changed 8 dependencies!
7 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.

更新后的 pubspec.yaml 文件:

pubspec.yaml
yaml
# ...
dev_dependencies:
  # ... added dependencies
  flutter_test:
    sdk: flutter
  flutter_lints: ^5.0.0
  integration_test:
    sdk: flutter
# ...

创建集成测试文件

#

集成测试位于 Flutter 项目内的单独目录中。

  1. 创建一个名为 integration_test 的新目录。
  2. 在该目录中添加一个名为 app_test.dart 的空文件。

生成的目录树应类似于以下内容:

counter_app/
  lib/
    main.dart
  integration_test/
    app_test.dart

编写集成测试

#

集成测试文件包含一个 Dart 代码文件,该文件依赖于 integration_testflutter_test 和你的应用的 Dart 文件。

  1. 在你喜欢的 IDE 中打开你的 integration_test/app_test.dart 文件。

  2. 复制以下代码并将其粘贴到你的 integration_test/app_test.dart 文件中。最后一个导入应该指向你的 counter_appmain.dart 文件。(此 import 指向名为 introduction 的示例应用。)

    integration_test/counter_test.dart
    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() {
      IntegrationTestWidgetsFlutterBinding.ensureInitialized();
    
      group('端到端测试', () {
        testWidgets('点击悬浮操作按钮,验证计数器',
            (tester) async {
          // 加载应用组件。
          await tester.pumpWidget(const MyApp());
    
          // 验证计数器从 0 开始。
          expect(find.text('0'), findsOneWidget);
    
          // 找到要点击的悬浮操作按钮。
          final fab = find.byKey(const ValueKey('increment'));
    
          // 模拟点击悬浮操作按钮。
          await tester.tap(fab);
    
          // 触发一个帧。
          await tester.pumpAndSettle();
    
          // 验证计数器递增 1。
          expect(find.text('1'), findsOneWidget);
        });
      });
    }

此示例包含三个步骤:

  1. 初始化 IntegrationTestWidgetsFlutterBinding。此单例服务在物理设备上执行测试。

  2. 使用 WidgetTester 类交互和测试组件。

  3. 测试重要的场景。

运行集成测试

#

运行的集成测试因测试的平台而异。

  • 要测试桌面平台,请使用命令行或 CI 系统。
  • 要测试移动平台,请使用命令行或 Firebase Test Lab。
  • 要在 Web 浏览器中进行测试,请使用命令行。

在桌面平台上测试

#
如果你使用 CI 系统测试 Linux 应用,请展开

要测试 Linux 应用,你的 CI 系统必须先调用 X 服务器。在 GitHub Action、GitLab Runner 或类似的配置文件中,将集成测试设置为_使用_ xvfb-run 工具。

这样做会调用一个 X 窗口系统,Flutter 可以在其中启动并测试你的 Linux 应用。

例如,使用 GitHub Actions,你的 jobs.setup.steps 应该包含一个类似于以下步骤的步骤:

yaml
      - name: Run Integration Tests
        uses: username/[email protected]
        with:
          run: flutter test integration_test -d linux -r github

这会在 X 窗口中启动集成测试。

如果你没有以这种方式配置集成,Flutter 会返回一个错误。

Building Linux application...
Error waiting for a debug connection: The log reader stopped unexpectedly, or never started.

要在 macOS、Windows 或 Linux 平台上进行测试,请完成以下任务:

  1. 从项目的根目录运行以下命令:

    flutter test integration_test/app_test.dart
  2. 如果可以选择要测试的平台,请选择桌面平台。输入 1 选择桌面平台。

根据平台的不同,命令结果应类似于以下输出。

PS C:\path\to\counter_app> flutter test .\integration_test\app_test.dart
正在解析依赖项...
正在下载软件包...
  flutter_lints 3.0.2(可用版本为 4.0.0)
  leak_tracker 10.0.4(可用版本为 10.0.5)
  leak_tracker_flutter_testing 3.0.3(可用版本为 3.0.5)
  lints 3.0.0(可用版本为 4.0.0)
  material_color_utilities 0.8.0(可用版本为 0.11.1)
  meta 1.12.0(可用版本为 1.15.0)
  test_api 0.7.0(可用版本为 0.7.1)
  vm_service 14.2.1(可用版本为 14.2.2)
已获取依赖项!
8 个软件包有与依赖项约束不兼容的更新版本。
尝试 `flutter pub outdated` 获取更多信息。

已连接设备:

Windows (desktop) • windows • windows-x64    • Microsoft Windows [版本 10.0.22631.3593]
Chrome (web)      • chrome  • web-javascript • Google Chrome 124.0.6367.207
Edge (web)        • edge    • web-javascript • Microsoft Edge 124.0.2478.97

[1]: Windows (windows)
[2]: Chrome (chrome)
[3]: Edge (edge)

请选择一个(或输入“q”退出):1

00:00 +0: 正在加载 C:/path/to/counter_app/integration_test/app_test.dart               B
00:29 +0: 正在加载 C:/path/to/counter_app/counter_app/integration_test/app_test.dart   29.1s
√ 已构建 build\windows\x64\runner\Debug\counter_app.exe
00:31 +1: 所有测试都已通过!
flutter test integration_test
正在解析依赖项...
正在下载软件包...
  flutter_lints 3.0.2(可用版本 4.0.0)
> leak_tracker 10.0.4(之前版本为 10.0.0)(可用版本 10.0.5)
> leak_tracker_flutter_testing 3.0.3(之前版本为 2.0.1)(可用版本 3.0.5)
> leak_tracker_testing 3.0.1(之前版本为 2.0.1)
  lints 3.0.0(可用版本 4.0.0)
  material_color_utilities 0.8.0(可用版本 0.11.1)
> meta 1.12.0(之前版本为 1.11.0)(可用版本 1.15.0)
> test_api 0.7.0(之前版本为 0.6.1)(可用版本 0.7.1)
> vm_service 14.2.1(之前版本为 13.0.0)(可用版本 14.2.2)
已更改 6 个依赖项!
8 个软件包有与依赖项约束不兼容的更新版本。
尝试使用 `flutter pub outdated` 获取更多信息。

已连接设备:

macOS(桌面)                 • macos                 • darwin-arm64   • macOS 14.4.1 23E224 darwin-arm64
Mac 设计用于 iPad(桌面) • mac-designed-for-ipad • darwin         • macOS 14.4.1 23E224 darwin-arm64
Chrome(网络)                    • chrome                • web-javascript • Google Chrome 124.0.6367.208

未找到无线设备。

[1]: macOS (macos)
[2]: Mac 设计用于 iPad (mac-designed-for-ipad)
[3]: Chrome (chrome)
请选择一个(或输入“q”退出):1

00:01 +0: 正在加载 /path/to/counter_app/integration_test/app_test.dart        R
00:02 +0: 正在加载 /path/to/counter_app/integration_test/app_test.dart    846ms
00:03 +0: 正在加载 /path/to/counter_app/integration_test/app_test.dart        B

正在构建 macOS 应用程序...
✓ 已构建 build/macos/Build/Products/Debug/counter_app.app
00:32 +1: 所有测试都已通过!
flutter test integration_test/app_test.dart

已连接设备:

Linux (桌面) • linux  • linux-x64      • Ubuntu 22.04.4 LTS 6.5.0-35-generic
Chrome (网页)    • chrome • web-javascript • Google Chrome 104.0.5112.101

[1]: Linux (linux)
[2]: Chrome (chrome)

请选择一个 (或输入 "q" 退出): 1

00:00 +0: /path/to/counter_app/integration_test/app_test.dart     B
00:16 +0: /path/to/counter_app/integration_test/app_test.dart

✓ 已构建 build/linux/x64/debug/bundle/counter_app

在移动设备上测试

#

要在真实的 iOS 或 Android 设备上进行测试,请完成以下任务:

  1. 连接设备。

  2. 从项目的根目录运行以下命令:

    flutter test integration_test/app_test.dart

    结果应类似于以下输出。此示例使用 iOS。

    flutter test integration_test/app_test.dart
    00:04 +0: loading /path/to/counter_app/integration_test/app_test.dart
    00:15 +0: loading /path/to/counter_app/integration_test/app_test.dart
    00:18 +0: loading /path/to/counter_app/integration_test/app_test.dart   2,387ms
    Xcode build done.                                           13.5s
    00:21 +1: All tests passed!
  3. 验证测试完成后是否已删除 Counter App。如果没有,后续测试将失败。如果需要,请点击该应用并从上下文菜单中选择 删除应用


在 Web 浏览器中测试

#

要在 Web 浏览器中进行测试,请执行以下步骤:

  1. ChromeDriver 安装到您选择的目录中。

    npx @puppeteer/browsers install chromedriver@stable

    为了简化安装,此命令使用@puppeteer/browsers Node 库。

  2. 将 ChromeDriver 的路径添加到您的 $PATH 环境变量中。

  3. 验证 ChromeDriver 安装是否成功。

    chromedriver --version
    ChromeDriver 124.0.6367.60 (8771130bd84f76d855ae42fbe02752b03e352f17-refs/branch-heads/6367@{#798})
  4. 在你的 counter_app 项目目录中,创建一个名为 test_driver 的新目录。

    mkdir test_driver
  5. 在此目录中,创建一个名为 integration_test.dart 的新文件。

  6. 复制以下代码并将其粘贴到你的 integration_test.dart 文件中。

    test_driver/integration_test.dart
    dart
    import 'package:integration_test/integration_test_driver.dart';
    
    Future<void> main() => integrationDriver();
  7. 启动 chromedriver,如下所示:

    chromedriver --port=4444
  8. 从项目的根目录运行以下命令:

    flutter drive \
      --driver=test_driver/integration_test.dart \
      --target=integration_test/app_test.dart \
      -d chrome

    响应应类似于以下输出:

    Resolving dependencies...
      leak_tracker 10.0.0 (10.0.5 available)
      leak_tracker_flutter_testing 2.0.1 (3.0.5 available)
      leak_tracker_testing 2.0.1 (3.0.1 available)
      material_color_utilities 0.8.0 (0.11.1 available)
      meta 1.11.0 (1.14.0 available)
      test_api 0.6.1 (0.7.1 available)
      vm_service 13.0.0 (14.2.1 available)
    Got dependencies!
    7 packages have newer versions incompatible with dependency constraints.
    Try `flutter pub outdated` for more information.
    Launching integration_test/app_test.dart on Chrome in debug mode...
    Waiting for connection from debug service on Chrome...             10.9s
    This app is linked to the debug service: ws://127.0.0.1:51523/3lofIjIdmbs=/ws
    Debug service listening on ws://127.0.0.1:51523/3lofIjIdmbs=/ws
    00:00 +0: end-to-end test tap on the floating action button, verify counter
    00:01 +1: (tearDownAll)
    00:01 +2: All tests passed!
    All tests passed.
    Application finished.

    要将其作为无头测试运行,请使用 -d web-server 选项运行 flutter drive

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

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


使用 Firebase Test Lab 进行测试

#

要测试 Android 和 iOS 目标,可以使用 Firebase Test Lab。

Android 设置

#

请按照自述文件中的Android 设备测试部分中的说明进行操作。

iOS 设置

#

请按照自述文件中的iOS 设备测试部分中的说明进行操作。

Test Lab 项目设置

#
  1. 启动你的Firebase 控制台

2.如有必要,创建一个新的 Firebase 项目。

  1. 导航到质量 > Test Lab

    Firebase Test Lab 控制台

上传 Android APK

#
  1. 使用 Gradle 创建 APK。

    pushd android
    # flutter build 在 android/ 中生成用于构建应用的文件
    flutter build apk
    ./gradlew app:assembleAndroidTest
    ./gradlew app:assembleDebug -Ptarget=integration_test/<name>_test.dart
    popd

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

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

Firebase Test Lab 上传
  1. 点击 运行测试

  2. 选择Instrumentation测试类型。

  3. 将 App APK 添加到App APK 或 AAB框中。

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

  4. 将 Test APK 添加到Test APK框中。

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

Firebase Test Lab 上传两个 APK

如果发生故障,请单击红色图标以查看输出:

Firebase Test Lab 测试结果

从命令行上传 Android APK

#

有关从命令行上传 APK 的说明,请参阅自述文件的Firebase Test Lab 部分

上传 Xcode 测试

#

要了解如何上传 .zip 文件,请查阅 Firebase 控制台 Firebase TestLab 部分中的Firebase TestLab iOS 说明

从命令行上传 Xcode 测试

#

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