How to Add a Custom Test Timeout in Flutter

Writing asynchronous tests with streams can be a challenge.

And if we’re not careful, we can end up with a test that “hangs” while waiting for stream values to be emitted.

Here’s an example:

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]),
    );
  },
);

The test above will wait and eventually timeout because the stream never emits the last expected value.

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

And if we have hundreds or thousands of tests running on CI, a default timeout of 30 seconds can cost us a lot of time and money. 💰

Setting a Custom Timeout

To work around this, we can add a timeout argument:

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)),
);

In this case, the test will still fail, but it will do so after 1 second.

The @Timeout annotation

But of we have a lot of tests, setting an individual timeout for each test is quite tedious.

Instead, we can define a @Timeout annotation that will apply to all the tests in the file:

// 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]),
      );
    },
  );
}

For more info, read the documentation of the official Dart test package:

Happy coding!

Flutter Foundations Course Now Available

I launched a brand new course that covers testing in great depth, along with other important topics like app architecture, state management, navigation & routing, and much more:

Want More?

Invest in yourself with my high-quality Flutter courses.

Flutter in Production

Flutter in Production

Learn about flavors, environments, error monitoring, analytics, release management, CI/CD, and finally ship your Flutter apps to the stores. 🚀

Flutter & Firebase Masterclass

Flutter & Firebase Masterclass

Learn about Firebase Auth, Cloud Firestore, Cloud Functions, Stripe payments, and much more by building a full-stack eCommerce app with Flutter & Firebase.

The Complete Dart Developer Guide

The Complete Dart Developer Guide

Learn Dart Programming in depth. Includes: basic to advanced topics, exercises, and projects. Last updated to Dart 2.15.

Flutter Animations Masterclass

Flutter Animations Masterclass

Master Flutter animations and build a completely custom habit tracking application.