Flutter项目Patrol测试未实际执行却显示通过,请求排查
问题描述
原正常运行的Integration Test配置
测试代码(integration_test/openapp_test.dart)
########## # integration_test/openapp_test.dart ########## import 'package:myapp/main.dart' as app; group('end-to-end test', () { testWidgets('tap on the floating action button, verify counter', (tester) async { app.main(isTesting: true); await tester.pumpAndSettle( const Duration(seconds: 10), ); // first screen expect(find.text('Mulai baru'), findsOneWidget); // I go to 'Login from Onboarding' page await tester.tap(find.byKey( const Key(OnboardingKey.buttonMasukKeAkun), )); }); });
Driver代码(test_driver/integration_test.dart)
########## # test_driver/integration_test.dart ########## // @dart=2.9 import 'package:integration_test/integration_test_driver.dart'; Future<void> main() => integrationDriver();
主程序代码(lib/main.dart)
########## # lib/main.dart ########## Future<void> main({bool isTesting = false}) async { WidgetsFlutterBinding.ensureInitialized(); await SystemChrome.setPreferredOrientations(<DeviceOrientation>[ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); await Firebase.initializeApp(); _initCrashlytics(); await SharedPreference.wipeSecureStorage(); runZonedGuarded<Future<void>>( () async { runApp(App(isTesting: isTesting)); }, (Object object, StackTrace stackTrace) { ... ... ,,, }, ); } class App extends StatelessWidget { const App({Key? key, this.isTesting = false}) : super(key: key); final bool isTesting; // This widget is the root of your application. @override Widget build(BuildContext context) { ... ... ... } }
运行命令
flutter drive --driver=test_driver/integration_test.dart --target=integration_test/openapp_test_copy.dart --flavor=staging
此命令可正常安装APK、执行测试并通过。
改用Patrol Test后的问题
修改后的测试代码(两种写法)
写法1:
########## # integration_test/openapp_test.dart ########## void main() { group('end-to-end test', () { patrolTest('tap on the floating action button, verify counter', (PatrolTester $) async { // app.main(isTesting: true); await $.pumpWidgetAndSettle( const App( isTesting: true, ), duration: const Duration(seconds: 20), ); await $.pump(const Duration(seconds: 50)); expect(find.text('Mulai baru'), findsNothing); }); }); }
写法2:
########## # integration_test/openapp_test.dart ########## void main() { group('end-to-end test', () { patrolTest('tap on the floating action button, verify counter', (PatrolTester $) async { await $.pumpWidget( const App( isTesting: true, ), ); await $.pumpAndSettle( duration: const Duration(seconds: 20), ); expect(find.text('Mulai baru'), findsNothing); }); }); }
运行命令
patrol test --flavor staging
问题现象
测试直接显示通过,但未看到应用安装及测试实际运行;且断言expect(find.text('Mulai baru'), findsNothing)本应失败(原测试中该文本存在),结果却不符合预期。
执行日志
FileSystemException: Cannot open file, path = '/Users/thekucays/.zshrc' (OS Error: Permission denied, errno = 13) No device specified, using the first one (P0AA003810060900077) Every test target will be run 1 time(s) • Building apk with entrypoint openapp_test.dart... ✓ Completed building apk with entrypoint openapp_test.dart (22.3s) • Executing tests of apk with entrypoint openapp_test.dart on device P0AA003810060900077... ✓ Completed executing tests of apk with entrypoint openapp_test.dart on device P0AA003810060900077 (12.2s) PASS openapp_test.dart on P0AA003810060900077
环境信息
flutter doctor -v输出
[!] Flutter (Channel stable, 3.7.1, on macOS 12.6.1 21G217 darwin-arm64, locale en-ID) • Flutter version 3.7.1 on channel stable at /Users/thekucays/fvm/versions/3.7.1 ! Warning: `dart` on your path resolves to /opt/homebrew/Cellar/dart/2.18.4/libexec/bin/dart, which is not inside your current Flutter SDK checkout at /Users/thekucays/fvm/versions/3.7.1. Consider adding /Users/thekucays/fvm/versions/3.7.1/bin to the front of your path. • Upstream repository https://github.com/flutter/flutter.git • Framework revision 7048ed95a5 (9 weeks ago), 2023-02-01 09:07:31 -0800 • Engine revision 800594f1f4 • Dart version 2.19.1 • DevTools version 2.20.1 • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades. [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/thekucays/Library/Android/sdk • Platform android-33, build-tools 33.0.0 • ANDROID_HOME = /Users/thekucays/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 13.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 13A1030d • CocoaPods version 1.12.0 [✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable. [✓] Android Studio (version 2021.3) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866) [✓] VS Code (version 1.73.1) • VS Code at /Users/thekucays/Documents/Installers/Visual Studio Code.app/Contents • Flutter extension version 3.60.0 [✓] Connected device (2 available) • Nokia 5 3 (mobile) • P0AA003810060900077 • android-arm64 • Android 11 (API 30) • macOS (desktop) • macos • darwin-arm64 • macOS 12.6.1 21G217 darwin-arm64 [✓] HTTP Host Availability • All required HTTP hosts are available
patrol doctor输出
Patrol CLI version: 1.1.3 Program adb found in /Users/thekucays/Library/Android/sdk/platform-tools/adb Env var $ANDROID_HOME set to /Users/thekucays/Library/Android/sdk Program xcodebuild found in /usr/bin/xcodebuild Program ideviceinstaller found in /opt/homebrew/bin/ideviceinstaller Program ios-deploy found in /opt/homebrew/bin/ios-deploy
patrol -V输出
patrol_cli v1.1.3
解决方案
1. 执行完整的应用初始化流程
你当前直接通过$.pumpWidget启动App,跳过了main函数中的关键初始化步骤(Flutter绑定初始化、Firebase初始化、SharedPreference清理等),导致App初始状态异常,页面元素未正确加载,断言无法触发预期结果。
应在Patrol测试中调用app.main(isTesting: true),而非直接渲染App组件:
import 'package:patrol/patrol.dart'; import 'package:myapp/main.dart' as app; void main() { group('end-to-end test', () { patrolTest('tap on the floating action button, verify counter', (PatrolTester $) async { // 调用main完成所有初始化工作 await app.main(isTesting: true); // 等待应用渲染稳定 await $.pumpAndSettle(const Duration(seconds: 10)); // 此时断言可正常验证元素存在 expect(find.text('Mulai baru'), findsOneWidget); }); }); }
2. 初始化Patrol测试绑定
在测试文件开头添加Patrol绑定初始化,确保测试环境正确配置:
import 'package:patrol/patrol.dart'; import 'package:myapp/main.dart' as app; void main() { PatrolTestBinding.ensureInitialized(); // 初始化Patrol绑定 group('end-to-end test', () { patrolTest('tap on the floating action button, verify counter', (PatrolTester $) async { await app.main(isTesting: true); await $.pumpAndSettle(const Duration(seconds: 10)); expect(find.text('Mulai baru'), findsOneWidget); }); }); }
3. 校验Patrol依赖版本
确保pubspec.yaml中Patrol依赖版本与CLI版本一致:
dev_dependencies: patrol: ^1.1.3 # 与patrol_cli版本匹配 integration_test: sdk: flutter
4. 查看设备端测试日志
通过adb logcat查看设备上的测试执行细节,确认测试是否真的运行及是否存在初始化错误:
adb logcat -s flutter
内容的提问来源于stack exchange,提问作者thekucays
相关产品推荐
相关产品推荐

