Flutter. How to test that there is no overflows with integration tests?
Asked Answered
D

2

9

I use flutter_driver to do my integration tests in Flutter. On some screens text on buttons gives overflow errors. I want to create a test which can show that overflow happened. So when I will run all integration tests on a bunch of virtual/real devices I can see that UI is not positioned correctly.

Dibasic answered 27/4, 2019 at 5:42 Comment(1)
Why integration test specifically? This can be tested using widget tests.Bedlamite
T
9

There is no need for integration tests for that. Widget tests will do.

Since Widget testing runs with asserts enabled, calling tester.pumpWidget with a widget that would overflow will throw an exception and therefore make a failing test.

For example, the following test will fail:

testWidgets('overflow', (tester) async {
  await tester.pumpWidget(Row(
    textDirection: TextDirection.ltr,
    children: <Widget>[
      // too big to fit in the default size of the row
      Container(width: 99999),
    ],
  ));
});

Note that the screen size for widget testing can be customized. See How to test Flutter widgets on different screen sizes?

Alternatively, we can wrap our tested widget into a Container like so:

await tester.pumpWidget(Container(
  alignment: Alignment.center,
  width: <my screen widget>,
  height: <my screen height>,
  child: <the widget which I want to test overflow on>,
);
Triaxial answered 5/5, 2019 at 14:18 Comment(1)
Using widget testing to catch Renderflex overflows is not working properly because we need to customize the screen size of the tester but the text size are not matching the real device text size. Please check this #62448398 and github.com/flutter/flutter/issues/59755Domingadomingo
R
0

I have published 3 helper functions on my package called hrk_flutter_test_batteries.
They are as follows:

  1. disableOverflowError()
  2. tester.getOverflowRenderFlexList()
  3. tester.expectNoOverflow()

You can use them as follows:

  1. First import the package
flutter pub add dev:hrk_flutter_test_batteries
  1. Source - get_overflow_render_flex_list_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hrk_flutter_test_batteries/hrk_flutter_test_batteries.dart';

void main() {
  group('getOverflowRenderFlexList()', () {
    const overflowFlexKey = Key('overflow_flex');
    final overflowFlexFinder = find.byKey(overflowFlexKey);

    // Doesn't work. See test/error/disable_overflow_error_test.dart
    // setUp(() {
    //   disableOverflowError();
    // });

    // Doesn't work. See test/error/disable_overflow_error_test.dart
    // setUpAll(() {
    //   disableOverflowError();
    // });

    // setUpAll(() {
    //   configureHrkLogging();
    //   packageLogger.level = Level.ALL;
    // });

    testWidgets('1', (tester) async {
      disableOverflowError();
      tester.view.physicalSize = Size(100, tester.view.physicalSize.height);
      addTearDown(() => tester.view.resetPhysicalSize());
      await tester.pumpWidget(const Row(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          SizedBox(width: 110),
        ],
      ));
      final overflowRenderFlexList = tester.getOverflowRenderFlexList();
      expect(overflowRenderFlexList.length, 1);
    });

    testWidgets('0', (tester) async {
      disableOverflowError();
      tester.view.physicalSize = Size(100, tester.view.physicalSize.height);
      addTearDown(() => tester.view.resetPhysicalSize());
      await tester.pumpWidget(const Row(
        key: overflowFlexKey,
        textDirection: TextDirection.ltr,
        children: <Widget>[
          SizedBox(width: 10),
        ],
      ));
      final overflowRenderFlexList = tester.getOverflowRenderFlexList();
      expect(overflowRenderFlexList.length, 0);
      tester.expectNoOverflow();
    });

    testWidgets('2', (tester) async {
      disableOverflowError();
      tester.view.physicalSize = Size(100, tester.view.physicalSize.height);
      addTearDown(() => tester.view.resetPhysicalSize());
      await tester.pumpWidget(const Column(
        children: [
          Row(
            textDirection: TextDirection.ltr,
            children: <Widget>[
              SizedBox(width: 110),
            ],
          ),
          Row(
            textDirection: TextDirection.ltr,
            children: <Widget>[
              SizedBox(width: 110),
            ],
          ),
        ],
      ));
      final overflowRenderFlexList = tester.getOverflowRenderFlexList();
      expect(overflowRenderFlexList.length, 2);
    });

    testWidgets('of, 2', (tester) async {
      disableOverflowError();
      tester.view.physicalSize = Size(100, tester.view.physicalSize.height);
      addTearDown(() => tester.view.resetPhysicalSize());
      await tester.pumpWidget(const Column(
        children: [
          Row(
            textDirection: TextDirection.ltr,
            children: <Widget>[
              SizedBox(width: 110),
            ],
          ),
          Column(
            key: overflowFlexKey,
            children: [
              Row(
                textDirection: TextDirection.ltr,
                children: <Widget>[
                  SizedBox(width: 110),
                ],
              ),
              Row(
                textDirection: TextDirection.ltr,
                children: <Widget>[
                  SizedBox(width: 110),
                ],
              ),
            ],
          ),
        ],
      ));
      final overflowRenderFlexList = tester.getOverflowRenderFlexList(
        of: overflowFlexFinder,
      );
      expect(overflowRenderFlexList.length, 2);
    });

    testWidgets('of, matchRoot, 1', (tester) async {
      disableOverflowError();
      tester.view.physicalSize = Size(100, tester.view.physicalSize.height);
      addTearDown(() => tester.view.resetPhysicalSize());
      await tester.pumpWidget(const Column(
        children: [
          Row(
            textDirection: TextDirection.ltr,
            children: <Widget>[
              SizedBox(width: 110),
            ],
          ),
          Row(
            key: overflowFlexKey,
            textDirection: TextDirection.ltr,
            children: <Widget>[
              SizedBox(width: 110),
            ],
          ),
        ],
      ));
      final overflowRenderFlexList = tester.getOverflowRenderFlexList(
        of: overflowFlexFinder,
        matchRoot: true,
      );
      expect(overflowRenderFlexList.length, 1);
    });
  });
}
Ringlet answered 29/7, 2023 at 19:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.