runTest method

  1. @override
Future<void> runTest (Future<void> testBody(), VoidCallback invariantTester, { String description: '', Duration timeout: const Duration(seconds: 2) })
override

Call the testBody inside a FakeAsync scope on which pump can advance time.

Returns a future which completes when the test has run.

Called by the testWidgets and benchmarkWidgets functions to run a test.

The invariantTester argument is called after the testBody's Future completes. If it throws, then the test is marked as failed.

The description is used by the LiveTestWidgetsFlutterBinding to show a label on the screen during the test. The description comes from the value passed to testWidgets. It must not be null.

Implementation

@override
Future<void> runTest(Future<void> testBody(), VoidCallback invariantTester, {
  String description = '',
  Duration timeout = const Duration(seconds: 2),
}) {
  assert(description != null);
  assert(!inTest);
  assert(_currentFakeAsync == null);
  assert(_clock == null);

  _timeout = timeout;
  _timeoutStopwatch = Stopwatch()..start();
  _timeoutTimer = Timer.periodic(const Duration(seconds: 1), _checkTimeout);
  _timeoutCompleter = Completer<void>();

  final FakeAsync fakeAsync = FakeAsync();
  _currentFakeAsync = fakeAsync; // reset in postTest
  _clock = fakeAsync.getClock(DateTime.utc(2015, 1, 1));
  Future<void> testBodyResult;
  fakeAsync.run((FakeAsync localFakeAsync) {
    assert(fakeAsync == _currentFakeAsync);
    assert(fakeAsync == localFakeAsync);
    testBodyResult = _runTest(testBody, invariantTester, description, timeout: _timeoutCompleter.future);
    assert(inTest);
  });

  return Future<void>.microtask(() async {
    // testBodyResult is a Future that was created in the Zone of the
    // fakeAsync. This means that if we await it here, it will register a
    // microtask to handle the future _in the fake async zone_. We avoid this
    // by calling '.then' in the current zone. While flushing the microtasks
    // of the fake-zone below, the new future will be completed and can then
    // be used without fakeAsync.
    final Future<void> resultFuture = testBodyResult.then<void>((_) {
      // Do nothing.
    });

    // Resolve interplay between fake async and real async calls.
    fakeAsync.flushMicrotasks();
    while (_pendingAsyncTasks != null) {
      await _pendingAsyncTasks.future;
      fakeAsync.flushMicrotasks();
    }
    return resultFuture;
  });
}