Flutter May 2, 2019

Understanding Async in Flutter Tests

Article Summary

Anthony Bullard from Flutter reveals why your widget tests might be lying to you. The culprit? FakeAsync zones that simulate time instead of experiencing it.

Flutter unit tests run in FakeAsync zones that fake timers and microtasks, making async code testable without real wall-clock time. This creates unexpected behavior when testing widgets with images, HTTP calls, or other truly asynchronous operations that cross zone boundaries.

Key Takeaways

Critical Insight

Flutter's FakeAsync testing zones speed up tests by simulating time, but developers must understand zone boundaries to avoid flaky tests when dealing with images and external async operations.

The article includes a specific pattern for building TestAssetBundle that solves the asset manifest problem, plus iron laws for testing image-heavy widgets.

About This Article

Problem

Anthony Bullard found that Flutter widget tests fail when images don't load. The asset manifest isn't created for tests, so AssetBundle can't get the image bytes. On top of that, the Flutter Engine decodes images asynchronously, which won't finish inside FakeAsync zones.

Solution

Bullard suggests building a custom AssetBundle subclass that loads image bytes before the tests start. Wrap images in SizedBox or ConstrainedBox to give them a fixed size when you know the dimensions ahead of time.

Impact

This approach removes implicit size assertions on images and stops test failures from crossing zone boundaries. Developers can write widget behavior tests that actually work without relying on asynchronous image operations.