'How to test Flutter widgets on different screen sizes?
I have a Flutter widget which shows extra data depending on the screen size. Does anyone know a way of testing this widget on multiple different screen sizes?
I've had a look through the widget_tester source code but can't find anything.
Solution 1:[1]
Not sure why but solution of @rémi-rousselet didn't work for me. I've had to specify screen size using binding.window.physicalSizeTestValue and binding.window.devicePixelRatioTestValue so that output is fully deterministic
I've added a little bit more code for flutter beginners like me. Check this:
void main() {
final TestWidgetsFlutterBinding binding =
TestWidgetsFlutterBinding.ensureInitialized();
testWidgets("Basic layout test (mobile device)", (tester) async {
binding.window.physicalSizeTestValue = Size(400, 200);
binding.window.devicePixelRatioTestValue = 1.0;
await tester.pumpWidget(new MyApp());
expect(find.byType(MyHomePage), findsOneWidget);
// etc.
});
}
Solution 2:[2]
There is a package called device_preview that can simulate your flutter app running on different devices.

Solution 3:[3]
@rémi-rousselet's solution works perfectly!
In addition if you want to test an orientation change, try this:
const double PORTRAIT_WIDTH = 400.0;
const double PORTRAIT_HEIGHT = 800.0;
const double LANDSCAPE_WIDTH = PORTRAIT_HEIGHT;
const double LANDSCAPE_HEIGHT = PORTRAIT_WIDTH;
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
await binding.setSurfaceSize(Size(PORTRAIT_WIDTH, PORTRAIT_HEIGHT));
await tester.pumpWidget(MyWidget());
// test in portrait
await binding.setSurfaceSize(Size(LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT));
await tester.pumpAndSettle();
// OrientationBuilder gets triggered
// test in landscape
Solution 4:[4]
You could try this widget to test your widgets changing screen size in realtime
Screen Size Test
https://pub.dev/packages/screen_size_test
Preview
Demo https://dartpad.dartlang.org/43d9c47a8bf031ce3ef2f6314c9dbd52
Code Sample
import 'package:screen_size_test/screen_size_test.dart';
...
MaterialApp(
title: 'Demo',
builder: (context, child) => ScreenSizeTest(
child: child,
),
home: Scaffold(
body: ListView(
children: List.generate(
20,
(index) => Container(
padding: EdgeInsets.all(10),
child: Placeholder(),
)),
),
),
)
Solution 5:[5]
Although @Rémi Rousselet's answer was very helpful it didn't completely solve my problem. It turns out that I could just wrap my widget under test in a MediaQuery widget and set the size.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
Widget makeTestableWidget({Widget child, Size size}) {
return MaterialApp(
home: MediaQuery(
data: MediaQueryData(size: size),
child: child,
),
);
}
testWidgets("tablet", (tester) async {
final testableWidget = makeTestableWidget(
child: WidgetUnderTest(),
size: Size(1024, 768),
);
...
});
testWidgets("phone", (tester) async {
final testableWidget = makeTestableWidget(
child: WidgetUnderTest(),
size: Size(375, 812),
);
...
});
}
Solution 6:[6]
Currently the safest way is to use setSurfaceSize
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets("foo", (tester) async {
tester.binding.setSurfaceSize(Size(400, 400));
// reset
tester.binding.setSurfaceSize(null);
// continue
});
}
See here for related Github issue
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | VizGhar |
| Solution 2 | Pegasis |
| Solution 3 | Mark |
| Solution 4 | Jorge Wander Santana Ureña |
| Solution 5 | Jordan Davies |
| Solution 6 | Dominik Roszkowski |

