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

qoefvg9y  于 2023-03-04  发布在  Flutter
关注(0)|答案(8)|浏览(143)

测试使用Ahem字体运行,字体太大了,有时会溢出,破坏测试。有些测试根本不关心溢出,所以应该有一种方法来停用它们。
我有许多测试在模拟器中运行正常,但在测试中中断。
我们不得不防止实际上永远不会溢出的小部件溢出,或者为测试提供字体,而不是Ahem,只是为了不溢出测试。溢出错误测试是没有意义的,除非你正在做“溢出错误测试”。
如何关闭这些错误,或者如何使测试忽略它们?

p1iqtdky

p1iqtdky1#

基于@RémiRousselet的回答,我开发了一个解决方案。

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

此函数仅忽略溢出异常。

inn6fuwd

inn6fuwd2#

您不能专门禁用溢出。但有几个替代方法:

  • 将字体更改为“真实的的”字体。您的测试不必使用Ahem字体。缺少文档,以下是添加此功能的问题:https://github.com/flutter/flutter/issues/17700
  • 更改虚拟屏幕大小。请参阅如何在不同的屏幕大小上测试Flutter widget?
  • FlutterError.onError设置为null
2nc8po8w

2nc8po8w3#

如果您的问题纯粹是由于Ahem字体太大引起的,您可以尝试使用可访问性textScaleFactor收缩所有文本,方法是将WidgetUnderTest Package 在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的大字体,因此将字体设置为最大设置的用户将能够使用您的应用程序。

xpcnnkqh

xpcnnkqh4#

稍微改进了爱德华多的回答:修复了检测测试,并对非溢出错误抛出实际异常,以便小部件测试实际中断。

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

k97glaaz5#

谢谢分享伙计们,它工作得很好!
对于任何想在测试中使用它的人:

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

nkcskrwz6#

如果是使用属性softWrap文本小部件上的溢出:错,像这样

Text(
           'text here',
            softWrap: false,
)
ohtdti5x

ohtdti5x7#

如果您的测试中只有一个异常抛出,您可以告诉您的测试期待它,如下所示。

expect(
      tester
          .takeException()
          .toString()
          .contains('A RenderFlex overflowed by'),
      true,
    );
yduiuuwa

yduiuuwa8#

一种集中的方式来做。

setUpAll(() async {
    FlutterError.onError = (FlutterErrorDetails details) {
      // Detect overflow error
      final exception = details.exception;
      bool isOverFlowError = false;
      if (exception is FlutterError) {
        isOverFlowError = !exception.diagnostics.any((e) => e.value.toString().contains('RenderFlex'));
      }

      if (isOverFlowError) {
        // If the error is an overflow error, then we can safely ignore it
        // because it's not a real error.
        return;
      } else {
        FlutterError.dumpErrorToConsole(details);
      }
    };
  });

相关问题