Repository: flutter/flutter
File: packages/flutter/test/material/bottom_sheet_test.dart (Dart)

Code before:
                          color: Theme.of(context).colorScheme.primary,
                          child: FilledButton(
                            onPressed: () {
                              Navigator.pop(context);
                            },
                            child: const Text('Close'),
                          ),
                        ),
                      );
                    },
                  );
                },
                child: const Text('X'),
              );
            },
          ),
        ),
      ),
    );

    await tester.tap(find.text('X'));
    await tester.pump();

    // Advance the animation by 1/3 of the duration.
    await tester.pump(const Duration(milliseconds: 100));
    expect(tester.getTopLeft(find.byKey(sheetKey)).dy, closeTo(547.3, 0.1));

    // Advance the animation to the end.
    await tester.pump(const Duration(milliseconds: 200));
    expect(tester.getTopLeft(find.byKey(sheetKey)).dy, equals(262.5));

    // Dismiss the bottom sheet.
    await tester.tap(find.widgetWithText(FilledButton, 'Close'));
    await tester.pump();

    // Advance the animation by 1/4 of the duration.
    await tester.pump(const Duration(milliseconds: 100));
    expect(tester.getTopLeft(find.byKey(sheetKey)).dy, closeTo(427.3, 0.1));

    // Advance the animation to the end.
    await tester.pump(const Duration(milliseconds: 200));
    expect(tester.getTopLeft(find.byKey(sheetKey)).dy, equals(600.0));
  });
}

class _TestPage extends StatelessWidget {
  const _TestPage({this.useRootNavigator});

  final bool? useRootNavigator;

  @override

Review comment (bug):
I'm scared of these magic numbers because they make the test prone to break (and difficult to debug) with the tiniest changes to the underlying implementation. I wonder if we can use a predictable curve such as `Curves.linear` and somehow express the sheet extent as a function of both the animation duration and the sheet's initial extent. 

For example, at 100ms it's at x, at 200ms it's at 2x, etc. That way even if the sheet's internal implementation changes, the test still reflects the relationship between the provided curve and the sheet's extension value.

Code after:
                  );
                },
                child: const Text('X'),
              );
            },
          ),
        ),
      ),
    );

    await tester.tap(find.text('X'));
    await tester.pump();

    // Advance the animation by 50ms.
    await tester.pump(const Duration(milliseconds: 50));
    final double openExtent1 = tester.getTopLeft(find.byKey(sheetKey)).dy;

    // Advance the animation by an additional 50ms.
    await tester.pump(const Duration(milliseconds: 50));
    final double openExtent2 = tester.getTopLeft(find.byKey(sheetKey)).dy;

    // Advance the animation by an additional 50ms.
    await tester.pump(const Duration(milliseconds: 50));
    final double openExtent3 = tester.getTopLeft(find.byKey(sheetKey)).dy;

    // For the linear curve, the distance covered in each time interval should
    // be the same.
    expect(openExtent1 - openExtent2, closeTo(openExtent2 - openExtent3, 0.1));
    await tester.pumpAndSettle();

    // Dismiss the bottom sheet.
    await tester.tap(find.widgetWithText(FilledButton, 'Close'));
    await tester.pumpAndSettle();
  });

  testWidgets('ModalBottomSheet uses AnimationStyle reverseCurve', (WidgetTester tester) async {
    final Key sheetKey = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: Builder(
            builder: (BuildContext context) {
              return GestureDetector(
                onTap: () {
                  showModalBottomSheet<void>(
                    context: context,
                    sheetAnimationStyle: const AnimationStyle(reverseCurve: Curves.linear),
                    builder: (BuildContext context) {
                      return SizedBox.expand(
                        key: sheetKey,