Flutter/Dart 缓慢的单元测试:每个文件需要 >4 秒才能开始运行

dad*_*860 5 optimization unit-testing execution-time flutter-test dart-test

我的一个包含 7 个空测试的测试文件需要5 秒多的时间才能开始运行。我flutter test在 VS Code 中使用了这两种方法以及 Dart 测试运行器,它们花费的时间大约相同。

我的整个测试套件包含约 150 个测试,需要30 秒以上才能完成,因为每个测试文件需要 3-7 秒才能开始运行。

launch.json(用于 Dart 测试运行程序)
    {
      "name": "Dart: Run all tests",
      "type": "dart",
      "request": "launch",
      "program": "./test/"
    },
Run Code Online (Sandbox Code Playgroud)

定时测试运行:

00:05 +1 -7: Some tests failed.
real    0m9.532s
user    0m0.075s
sys     0m0.138s
Run Code Online (Sandbox Code Playgroud)

我正在使用嵌套组块,但我不认为这会导致如此巨大的延迟,从而使 TDD 极其缓慢

代码示例部分
00:05 +1 -7: Some tests failed.
real    0m9.532s
user    0m0.075s
sys     0m0.138s
Run Code Online (Sandbox Code Playgroud)

我什至尝试过分别测试和组合测试两个空的示例测试文件(参见下面的代码),单独运行都需要 4 秒以上的时间。如果我将两个测试文件合并为一个文件,则执行时间几乎与仅一个测试相同。

问题似乎在于启动每个测试文件,而不是测试本身。

测试

test_test_1.dart
void main() {
  group('AuthCubit:', () {

    late AuthCubit          authCubit;
    late MockLogIn          logIn;
    late MockLogOut         logOut;
    late MockRestoreSession restoreSession;

    setUp(() {
      logIn         = MockLogIn();
      logOut        = MockLogOut();
      restoreSession= MockRestoreSession();
      authCubit     = AuthCubit(
        logIn         : logIn,
        logOut        : logOut,
        restoreSession: restoreSession,
      );
    });

    tearDown(() {
      authCubit.close();
    });

    test('initial state is unauthenticated', () async {
      expect(authCubit.state, equals(const AuthStateUnauthenticated()));
    });
    group('logIn():', () {
      //? Create late variables that all stages use, if needed
      setUp(() {});
      //? Create subgroups for stages this function will step through
      group('On failure:', () {
        setUp(() {});
        test('emits unauthenticated state', () async { throw UnimplementedError(); });
      });
      group('On success:', () {
        setUp(() {});
        test('emits authenticated state', () async { throw UnimplementedError(); });
      });
    });
  });
  // ... + similar empty tests for other functions ...
}
Run Code Online (Sandbox Code Playgroud) 测试_测试_2.dart

import 'package:flutter_test/flutter_test.dart';

//? Create Mocks, Fakes, etc, if needed

void main() {
  group('Test File 1:', () {
    //? Create late variables that all functions use, if needed
    test('empty test 1', () async { throw UnimplementedError(); });
    test('empty test 2', () async { throw UnimplementedError(); });
    test('empty test 3', () async { throw UnimplementedError(); });
    test('empty test 4', () async { throw UnimplementedError(); });
    test('empty test 5', () async { throw UnimplementedError(); });
  });
}

Run Code Online (Sandbox Code Playgroud) test_test_1_2.dart

import 'package:flutter_test/flutter_test.dart';

//? Create Mocks, Fakes, etc, if needed

void main() {
  group('Test File 2:', () {
    //? Create late variables that all functions use, if needed
    test('empty test 1', () async { throw UnimplementedError(); });
    test('empty test 2', () async { throw UnimplementedError(); });
    test('empty test 3', () async { throw UnimplementedError(); });
    test('empty test 4', () async { throw UnimplementedError(); });
    test('empty test 5', () async { throw UnimplementedError(); });
  });
}

Run Code Online (Sandbox Code Playgroud)

结果

test_test_1.dart 个人结果
00:04 +0 -5: Some tests failed.

real    0m8.743s
user    0m0.060s
sys     0m0.167s
Run Code Online (Sandbox Code Playgroud) `test_test_2.dart` 个人结果
00:05 +0 -5: Some tests failed.

real    0m8.982s
user    0m0.137s
sys     0m0.106s
Run Code Online (Sandbox Code Playgroud) `test_test_1_2.dart` 单独结果
00:04 +0 -10: Some tests failed.

real    0m8.602s << Note this is actually FASTER than the smaller test files
user    0m0.045s << same ^
sys     0m0.200s
Run Code Online (Sandbox Code Playgroud) 所有 3 个测试文件结果(一次运行)
00:08 +0 -20: Some tests failed.

real    0m12.696s
user    0m0.015s << Weirdly, this is the smallest value out of all test cases
sys     0m0.152s
Run Code Online (Sandbox Code Playgroud)

问题

我的代码、设置(软件或硬件)、Dart/Flutter 或其他方面可能存在什么问题?

假装我对 Flutter、Dart 或 VS Code 一无所知;哪些问题有助于找到潜在原因和解决方案?

dad*_*860 2

GitHub 上的jensjoha通过创建“嵌套聚合测试文件”帮助我找到了解决方法

在更高级别的注释中,我可能应该补充一点,对于您进行测试的每个文件,运行测试会变慢,因为它必须进行编译、启动新进程等。同样,正如我们所见,达到了这样的程度:它实际上开始做一些测试需要相当长的时间,所以运行 flutter test Specificfile.dart (至少对于许多特定文件来说)并不是很好。作为一种解决方法 - 当您想要运行所有测试时 - 您可以尝试创建一个测试文件,如#86722(评论)中所做的那样,然后仅运行该文件。

例子

// test_group_1_test.dart

import test_file_1_test.dart as testFile1;
import test_file_2_test.dart as testFile2;
// ...

void main() {
  group("test file 1", testFile1.main);
  group("test file 2", testFile2.main);
  // ...
}

Run Code Online (Sandbox Code Playgroud)
// everything_test.dart

import test_group_1_test.dart as testGroup1
import test_group_2_test.dart as testGroup2
// ...

void main() {
  group("test group 1", testGroup1.main);
  group("test group 2", testGroup2.main);
  // ...
}

Run Code Online (Sandbox Code Playgroud)

通过这种结构,我可以在运行单个测试文件所需的时间内运行所有(或任何组)测试文件,对于我的情况来说,速度快了约 75%。