集成测试
本篇描述了如何使用 integration_test
package 来运行集成测试。使用该 package 编写的测试具有以下特性:
-
兼容
flutter drive
指令,用于在真机或模拟器上运行测试。 -
能够通过 Firebase Test Lab 在各种设备上进行自动化测试。
-
兼容 flutter_test API,能够使用类似 widget 测试 的风格进行编写。
概览
单元测试、Widget 测试和集成测试
Flutter 支持三种类型的测试。 单元测试 验证一个方法或类的行为。 Widget 测试 无需运行应用程序就可以验证 Flutter widget 的行为。 集成测试(又名端到端测试或 GUI 测试)运行整个应用程序。
宿主和目标设备
在开发过程中,宿主 就是你的编码平台,应用程序在 目标 设备上运行,就像你在台式电脑上编写代码,并在移动设备、浏览器或者桌面程序上运行你的应用程序,(如果你使用的是 web 浏览器或桌面应用程序,宿主也是目标设备)
integration_test
integration_test package
用 integration_test
package 编写的测试可以:
-
直接在目标设备上运行,允许使用 Firebase Test Lab 在多个 Android/iOS 设备上进行测试。
-
使用
flutter test integration_test
指令运行。 -
使用
flutter_test
API,让集成测试编写风格更像 Widget 测试。
从 flutter_driver 迁移
现在还在使用 flutter_driver
的项目可以通过以下方式迁移到 integration_test
,请查看 从 flutter_driver 迁移 指南。
项目设置
在你的 pubspec.yaml
文件中加入 integration_test
和 flutter_test
:
$ 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);
});
}
目录结构
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();
然后将 IntegrationTestWidgetsFlutterBinding.ensureInitialized()
添加到你的 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() {
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
了解更多信息,请查看 Running Flutter driver tests with web 指南。
在 Firebase Test Lab 进行测试
你可以通过 Firebase Test Lab 同时使用 Android 和 iOS 目标设备进行测试。
Android 设置
请遵循 integration_test
README 中的 Android Device Testing 进行设置。
iOS 设置
请遵循 integration_test
README 中的 iOS Device Testing 进行设置。
Firebase Test Lab 项目设置
进入 Firebase 控制台, 如果你还没有新的项目,就创建一个新项目。然后导航菜单到 Quality > Test Lab:
上传 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
是在刚才 项目设置 创建的文件。
将 <flutter_project_directory>/build/app/outputs/apk/debug
内打包完成的 “debug” APK 文件上传到网页上的 Android Robo Test。这将启动一个 Robo 测试,并允许你运行其他测试:
点击 Run a test, 选择 Instrumentation 测试类型,并上传以下两个文件
<flutter_project_directory>/build/app/outputs/apk/debug/<file>.apk
<flutter_project_directory>/build/app/outputs/apk/androidTest/debug/<file>.apk
如果发生故障,你可以通过选择红色图标查看输出内容:
通过指令上传 Android APK
关于通过指令上传 APK 的说明,请查看 integration_test
README 中的 Firebase Test Lab。
上传 Xcode 测试
了解如何将 .zip 文件上传到 Firebase 控制台的 Firebase Test Lab,请查看 Firebase TestLab iOS instructions。
通过指令上传 Xcode 测试
关于如何通过指令上传 .zip 文件的说明,请查看 integration_test
README 中的 iOS Device Testing。