依次运行 Flutter Package 单元测试

问题描述 投票:0回答:3

我正在为自定义 Flutter 包编写一堆带有 HTTP 客户端的单元测试。

我注意到,当我使用

flutter test
运行测试时,前两个单元测试将大约在同一时间开始。

这不是我想要的。因为单元测试应该写入一些数据,并且在每个单元测试开始时数据都会被重置。这样每个测试都以相同的数据开始。

但是由于有两个测试同时运行,它们都访问同一个文件并损坏它或无法使用

FileSystemException: lock failed
访问它。

有没有办法强制测试一项一项地运行,而不是一次运行多个? 我尝试将它们放在单独的文件中,但这不起作用。

谢谢

unit-testing flutter dart
3个回答
4
投票

默认情况下,

flutter test
命令会并发执行测试,但您可以在flutter测试命令中使用
-j, --concurrency=<jobs>
指定并发度。

根据 Flutter 帮助文档:

-j, --concurrency=<jobs>
定义要运行的并发测试进程的数量。运行集成测试时这将被忽略。 (默认为“14”)

执行以下命令来一一运行所有测试

flutter test -j, --concurrency=1

执行以下命令以覆盖率一一运行所有测试,

flutter test --coverage -j, --concurrency=1

3
投票

如果您有多个彼此相关的测试,请使用测试包提供的组功能将它们组合起来。

请检查https://flutter.dev/docs/cookbook/testing/unit/introduction#5-combine-multiple-tests-in-a-group


0
投票

我遇到了类似的问题,我需要按顺序运行一堆测试。我使用 futures 将这个近似信号量的小东西组合在一起,这对我的用例有用,也许对其他人也有用

您创建一个“序列”,然后将测试包装在

runInSequence(...)
中,如下所示

void main() {
  final seq = newTestSequence();

  for (int i = 1; i <= 10; i++) {
    test('test $i', () async {
      await runInSequence(seq, () async {
        print('starting test $i...');

        // your test code goes here
        final sleepMs = 1000 - i * 10;
        await Future.delayed(Duration(milliseconds: sleepMs));

        print('test $i done');
      });
    });
  }
}

这是

newSequence
runInSequence

的代码
import 'dart:async';
import 'package:flutter/widgets.dart';

final Map<Key, Completer> _semaphores = {};

Key newTestSequence() {
  final sequence = GlobalKey();

  // create a new "semaphore" that will allow the first awaiter through
  // immediately
  _semaphores[sequence] = Completer();
  _semaphores[sequence]!.complete();

  return sequence;
}

Future<void> runInSequence(Key sequence, Future Function() test) async {
  // block until resource is acquired
  final c = await _claimSemaphore(sequence);

  // execute test
  await test();

  // release resource
  c.complete();
}

Future<Completer> _claimSemaphore(Key sequence) async {
  if (!_semaphores.containsKey(sequence)) {
    throw "unknown sequence $sequence; create one using `newTestSequence`";
  }

  final Completer c = _semaphores[sequence]!;

  // block execution until the future is completed
  await c.future;

  // replace completer because futures can only be completed once
  _semaphores[sequence] = Completer();

  return _semaphores[sequence]!;
}
© www.soinside.com 2019 - 2024. All rights reserved.