runTest method

  1. @override
Future<void> runTest(
  1. Future<void> testBody(),
  2. VoidCallback invariantTester, {
  3. String description = '',
})
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.

Implementation

@override
Future<void> runTest(
  Future<void> Function() testBody,
  VoidCallback invariantTester, {
  String description = '',
}) {
  assert(!inTest);
  assert(_currentFakeAsync == null);
  assert(_clock == null);

  final FakeAsync fakeAsync = FakeAsync();
  _currentFakeAsync = fakeAsync; // reset in postTest
  _clock = fakeAsync.getClock(DateTime.utc(2015));
  late Future<void> testBodyResult;
  fakeAsync.run((FakeAsync localFakeAsync) {
    assert(fakeAsync == _currentFakeAsync);
    assert(fakeAsync == localFakeAsync);
    testBodyResult = _runTest(testBody, invariantTester, description);
    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;
  });
}