如何在Flutter中添加自定义测试超时的方法

314 阅读1分钟

用流编写异步测试是一个挑战。

如果我们不小心,我们可能会在等待流值发射的过程中出现测试 "挂起"。

这里有一个例子。

test(
  'test timeout',
  () async {
    final controller = StreamController<int>();
    // add some values (without closing the controller)
    controller.addStream(Stream.fromIterable([1, 2, 3]));
    await expectLater(
      controller.stream,
      emitsInOrder([1, 2, 3, 4]),
    );
  },
);

上面的测试将等待并最终超时,因为流从未发出最后的预期值。

TimeoutException after 0:00:30.000000: Test timed out after 30 seconds.

如果我们有成百上千的测试在CI上运行,默认的30秒超时会让我们损失大量的时间和金钱。💰

设置一个自定义超时

为了解决这个问题,我们可以添加一个超时参数。

test(
  'test timeout',
  () async {
    final controller = StreamController<int>();
    // add some values (without closing the controller)
    controller.addStream(Stream.fromIterable([1, 2, 3]));
    await expectLater(
      controller.stream,
      emitsInOrder([1, 2, 3, 4]),
    );
  },
  // 30 seconds is too long. This is much better:
  timeout: const Timeout(Duration(seconds: 1)),
);

在这种情况下,测试仍然会失败,但它会在1秒后失败。

@Timeout 注解

但是如果我们有很多的测试,为每个测试设置单独的超时是相当繁琐的。

相反,我们可以定义一个@Timeout 注解,它将适用于文件中的所有测试。

// Note: this has to be on the very first line:
@Timeout(Duration(seconds: 1))
import 'dart:async';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test(
    'test timeout',
    () async {
      final controller = StreamController<int>();
      // add some values (without closing the controller)
      controller.addStream(Stream.fromIterable([1, 2, 3]));
      await expectLater(
        controller.stream,
        emitsInOrder([1, 2, 3, 4]),
      );
    },
  );
}

欲了解更多信息,请阅读官方Dart测试包的文档。

编码愉快!