用流编写异步测试是一个挑战。
如果我们不小心,我们可能会在等待流值发射的过程中出现测试 "挂起"。
这里有一个例子。
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测试包的文档。
编码愉快!