How to deactivate or ignore layout overflow messages in Flutter widget tests?
Solution 1
Based on @RémiRousselet answer, I developed a solution.
FlutterError.onError = _onError_ignoreOverflowErrors;
Function _onError_ignoreOverflowErrors = (
FlutterErrorDetails details, {
bool forceReport = false,
}) {
assert(details != null);
assert(details.exception != null);
// ---
bool ifIsOverflowError = false;
// Detect overflow error.
var exception = details.exception;
if (exception is FlutterError)
ifIsOverflowError = !exception.diagnostics
.any((e) => e.value.toString().startsWith("A RenderFlex overflowed by"));
// Ignore if is overflow error.
if (ifIsOverflowError)
print('Overflow error.');
// Throw others errors.
else
FlutterError.dumpErrorToConsole(details, forceReport: forceReport);
};
This function ignores just overflow exceptions.
Solution 2
If your problem is caused purely by the Ahem font being a little too big, you can try shrinking all your text using the accessibility textScaleFactor, by wrapping your WidgetUnderTest in a MediaQuery like so:
MediaQuery(
// Shrink the text avoid overflow caused by large Ahem font.
data: MediaQueryData(textScaleFactor: 0.5),
child: WidgetUnderTest(),
);
This should be much faster than loading a different font in your widget test, and doesn't introduce risk of missing errors by messing with FlutterError.onError
. However, if your widget doesn't honor textScaleFactor, or if the overflow is caused by some other reason, this won't help.
Please note that this is probably hiding an actual problem. The best solution is to fix or redesign your UI so that it won't overflow even with testScaleFactor: 1.5 in a large font, so users who set their fonts to the largest setting will be able to use your apps.
Solution 3
You cannot disable overflow specifically. But there are a few alternatives:
- Change the font to a "real" font. Your tests don't have to use Ahem font. The documentation is lacking, here's the issue that added this feature: https://github.com/flutter/flutter/issues/17700
- Change the virtual screen size. See How to test Flutter widgets on different screen sizes?
- set
FlutterError.onError
tonull
Solution 4
Slightly improved Eduardo's answer: fixed the detection test, and throwing an actual exception for non-overflow errors, so that widget tests will actually break.
Function onError_ignoreOverflowErrors = (
FlutterErrorDetails details, {
bool forceReport = false,
}) {
assert(details != null);
assert(details.exception != null);
var isOverflowError = false;
// Detect overflow error.
var exception = details.exception;
if (exception is FlutterError) {
isOverflowError = exception.diagnostics.any((e) => e.value.toString().contains("A RenderFlex overflowed by"));
}
// Ignore if is overflow error: only report to the console, but do not throw exception as it will
// cause widget tests to fail.
if (isOverflowError) {
FlutterError.dumpErrorToConsole(details, forceReport: forceReport);
} else {
FlutterError.dumpErrorToConsole(details, forceReport: forceReport);
throw (exception);
}
};
Solution 5
Thanks for sharing guys, it works just fine!
To anyone who wants to use it in a test:
testWidgets('your test name', (tester) async {
disableOverflowErrors();
});
void disableOverflowErrors() {
//TODO MyScreen throws overflow error. Will be investigate in a different ticket.
FlutterError.onError = (FlutterErrorDetails details) {
final exception = details.exception;
final isOverflowError = exception is FlutterError &&
!exception.diagnostics.any(
(e) => e.value.toString().startsWith("A RenderFlex overflowed by"));
if (isOverflowError) {
print(details);
} else {
FlutterError.presentError(details);
}
};
}
MarcG
Currently living in São Paulo and Rio de Janeiro - Brazil. I hold both Brazilian and European (Polish) passports. Aeronautical-Mechanical Engineer (Technological Institute of Aeronautics ITA, the "Brazilian MIT"). MBA (PUC-RJ) Software Architect and Developer. Previously C++, but now mostly Dart/Flutter (see https://pub.dev/publishers/glasberg.dev/packages), JavaScript (Typescript) and Java. Love TDD, BDD and Clean Code. Also very interested in Usability and Gamification. Excellent communication skills and technical writing. I program since I was 10 yo. Love travelling, astronomy, science and games (playing and making them). Links: https://github.com/marcglasberg https://www.linkedin.com/in/marcglasberg/ https://medium.com/flutter-community/https-medium-com-marcglasberg-async-redux-33ac5e27d5f6 https://medium.com/flutter-community/i18n-extension-flutter-b966f4c65df9 Patents: https://www.google.com/patents/US7917437 https://www.google.com/patents/US7596530 Fluent English and Portuguese, good Spanish, some French. Come visit Rio and rent my place in AirBnB: https://www.airbnb.com/rooms/13830632 [email protected]
Updated on December 13, 2022Comments
-
MarcG over 1 year
Tests run with the Ahem font, which is too big, and sometimes it overflows, breaking tests. Some tests don't care about overflow anyway, so there should be a way to deactivate them.
I have many tests which run OK in the simulator, but break in tests.
We are forced to prevent overflows for widgets which will never overflow in reality, or else provide fonts for the tests, instead of Ahem, just for the sake of not overflowing the tests. It makes no sense that overflow errors are tested, unless you are doing "overflow error tests".
How do I turn off these errors, or how do I make tests ignore them?