benchmarkWidgets function

Future<void> benchmarkWidgets(
  1. WidgetTesterCallback callback,
  2. {bool mayRunWithAsserts = false,
  3. bool semanticsEnabled = 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!

If the semanticsEnabled parameter is set to true, WidgetTester.ensureSemantics will have been called before the tester is passed to the callback, and that handle will automatically be disposed after the callback is finished.

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

Example:

main() async {
  assert(false); // fail in debug mode
  await benchmarkWidgets((WidgetTester tester) async {
    await tester.pumpWidget(MyWidget());
    final Stopwatch timer = 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,
  bool semanticsEnabled = false,
}) {
  assert(() {
    if (mayRunWithAsserts) {
      return true;
    }
    debugPrint(kDebugWarning);
    return true;
  }());
  final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
  assert(binding is! AutomatedTestWidgetsFlutterBinding);
  final WidgetTester tester = WidgetTester._(binding);
  SemanticsHandle? semanticsHandle;
  if (semanticsEnabled) {
    semanticsHandle = tester.ensureSemantics();
  }
  tester._recordNumberOfSemanticsHandles();
  return binding.runTest(
    () async {
      await callback(tester);
      semanticsHandle?.dispose();
    },
    tester._endOfTestVerifications,
  );
}