如何在Flutter小部件测试中停用或忽略布局溢出消息?

时间:2019-08-14 17:05:39

标签: testing layout flutter flutter-test

测试使用 Ahem字体运行,该字体太大,有时会溢出,从而破坏测试。某些测试无论如何都不会在意溢出,因此应该有一种停用它们的方法。

我有很多测试可以在模拟器中正常运行,但是会中断测试。

我们被迫防止实际上不会溢出的窗口小部件溢出,或者为了不溢出测试,而为Ahem提供测试字体,而不是Ahem。除非您正在执行“溢出错误测试”,否则测试溢出错误毫无意义。

如何关闭这些错误,或者如何使测试忽略它们?

4 个答案:

答案 0 :(得分:3)

您不能专门禁用溢出。但是有几种选择:

答案 1 :(得分:3)

如果您的问题是完全由 Ahem字体引起的,则可以尝试使用可访问性textScaleFactor来缩小所有文本,方法是将WidgetUnderTest包裹在MediaQuery中,如下所示:

MediaQuery(
  // Shrink the text avoid overflow caused by large Ahem font.
  data: MediaQueryData(textScaleFactor: 0.5),
  child: WidgetUnderTest(),
);

这应该比在窗口小部件测试中加载其他字体快得多,并且不会因与FlutterError.onError混乱而造成丢失错误的风险。但是,如果您的窗口小部件不支持textScaleFactor,或者如果溢出是由其他原因引起的,则将无济于事。

请注意,这可能隐藏了一个实际问题。最好的解决方案是修复或重新设计UI,以使即使使用testScaleFactor:1.5大字体也不会溢出,因此将字体设置为最大设置的用户将能够使用您的应用。

答案 2 :(得分:0)

基于https://ewuradjango.herokuapp.com/profiles的答案,我开发了一个解决方案。

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);
};

此函数将忽略仅溢出异常。

答案 3 :(得分:0)

稍微改进了 Eduardo 的回答:修复了检测测试,并为非溢出错误抛出实际异常,以便小部件测试实际上会中断。

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);
  }
};