benchmarkWidgets function

Future<void> benchmarkWidgets (WidgetTesterCallback callback, { bool mayRunWithAsserts: false })

Runs the callback inside the Flutter benchmark environment.

Use this function for benchmarking custom StatelessWidgets and StatefulWidgets when you want to be able to use features from TestWidgetsFlutterBinding. The callback, when run, will be given a new instance of WidgetTester. The find object provides convenient widget Finders for use with the WidgetTester.

The callback can be asynchronous (using async/await or using explicit Futures). If it is, then benchmarkWidgets will return a Future that completes when the callback's does. Otherwise, it will return a Future that is always complete.

If the callback is asynchronous, make sure you await the call to benchmarkWidgets, otherwise it won't run!

Benchmarks must not be run in checked mode, because the performance is not representative. To avoid this, this function will print a big message if it is run in checked mode. Unit tests of this method pass mayRunWithAsserts, but it should not be used for actual benchmarking.

Example:

main() async {
  assert(false); // fail in checked mode
  await benchmarkWidgets((WidgetTester tester) async {
    await tester.pumpWidget(new MyWidget());
    final Stopwatch timer = new Stopwatch()..start();
    for (int index = 0; index < 10000; index += 1) {
      await tester.tap(find.text('Tap me'));
      await tester.pump();
    }
    timer.stop();
    debugPrint('Time taken: ${timer.elapsedMilliseconds}ms');
  });
  exit(0);
}

Implementation

Future<void> benchmarkWidgets(WidgetTesterCallback callback, {bool mayRunWithAsserts = false}) {
  assert(() {
    if (mayRunWithAsserts)
      return true;

    print('┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓');
    print('┇ ⚠ THIS BENCHMARK IS BEING RUN WITH ASSERTS ENABLED ⚠  ┇');
    print('┡╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┦');
    print('│                                                       │');
    print('│  Numbers obtained from a benchmark while asserts are  │');
    print('│  enabled will not accurately reflect the performance  │');
    print('│  that will be experienced by end users using release  ╎');
    print('│  builds. Benchmarks should be run using this command  ┆');
    print('│  line:  flutter run --release benchmark.dart          ┊');
    print('│                                                        ');
    print('└─────────────────────────────────────────────────╌┄┈  🐢');
    return true;
  }());
  final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
  assert(binding is! AutomatedTestWidgetsFlutterBinding);
  final WidgetTester tester = WidgetTester._(binding);
  tester._recordNumberOfSemanticsHandles();
  return binding.runTest(
    () => callback(tester),
    tester._endOfTestVerifications,
  ) ?? Future<void>.value();
}