Flutter integration_test如何在同一会话中运行多个测试用例
问题原因
integration_test 包默认开启了测试用例间的环境隔离机制,每个testWidgets执行完成后会自动重置应用实例,所以你把app.main()放到group外或者group内的公共位置,第一个测试跑完后应用就被销毁了,第二个测试自然无法正常运行。这和旧版Flutter Driver默认复用同一会话的逻辑不同。
解决方案
方案1:关闭测试间隔离(推荐,可保留独立测试用例名称)
Flutter 3.10+版本的integration_test提供了关闭环境自动重置的配置,你可以直接通过该配置实现多个测试用例复用同一个应用会话,和你之前用Flutter Driver的逻辑完全对齐:
import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; // 导入你项目的main文件 import 'package:your_app/main.dart' as app; void main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); // 核心配置:关闭测试用例间的环境自动重置,保留应用状态 binding.resetTestEnvironmentBetweenTests = false; group('集成测试组', () { // 整个测试组启动前仅初始化一次应用 setUpAll(() async { app.main(); await tester.pumpAndSettle(); // 如果有通用前置操作比如登录,也可以放在这里执行一次 }); testWidgets('test 1:点击按钮计数器自增', (WidgetTester tester) async { await tester.tap(find.byKey(const Key('increment_button'))); await tester.pumpAndSettle(); expect(find.text('1'), findsOneWidget); }); testWidgets('test 2:再次点击按钮计数器再次自增', (WidgetTester tester) async { await tester.tap(find.byKey(const Key('increment_button'))); await tester.pumpAndSettle(); expect(find.text('2'), findsOneWidget); }); testWidgets('test 3:其他测试逻辑', (WidgetTester tester) async { // 后续所有测试都会复用同一个应用会话 }); }); }
方案2:单测试用例嵌套测试逻辑(兼容低版本Flutter)
如果你使用的Flutter版本低于3.10,没有resetTestEnvironmentBetweenTests配置,可以把所有测试逻辑放在同一个testWidgets内,嵌套普通test方法来区分测试步骤,同时保留测试名称输出:
import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:your_app/main.dart' as app; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('集成测试组', () { testWidgets('全量测试流程', (WidgetTester tester) async { // 只初始化一次应用 app.main(); await tester.pumpAndSettle(); // 测试1 test('test 1:点击按钮计数器自增', () async { await tester.tap(find.byKey(const Key('increment_button'))); await tester.pumpAndSettle(); expect(find.text('1'), findsOneWidget); }); // 测试2 test('test 2:再次点击按钮计数器再次自增', () async { await tester.tap(find.byKey(const Key('increment_button'))); await tester.pumpAndSettle(); expect(find.text('2'), findsOneWidget); }); // 测试3 test('test 3:其他测试逻辑', () async { // 你的测试逻辑 }); }); }); }
注意事项
- 关闭测试隔离后,测试用例会按照编写顺序执行,前一个测试的状态会影响后一个测试,需要保证测试用例的执行逻辑是线性连贯的
- 如果部分测试需要全新的应用状态,可以单独拆分到其他测试组,或者在对应测试执行完成后手动重置应用状态
内容的提问来源于stack exchange,提问作者Łukasz Dębowski
相关产品推荐
相关产品推荐

