You need to enable JavaScript to run this app. Flutter integration_test如何在同一会话中运行多个测试用例
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 05:51:01