runTest method
- @override
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;
});
}