skip to Main Content

I’m trying to write test for my SliverAppBar example app. But failing to find title text ("SliverAppBar") of flexibleSpace after dragging down first item of SliverList by test.

Here is the code of my app:


import 'package:flutter/material.dart';

void main() {
  runApp(const StretchableSliverAppBar());
}

class StretchableSliverAppBar extends StatefulWidget {
  const StretchableSliverAppBar({super.key});

  @override
  State<StretchableSliverAppBar> createState() =>
      _StretchableSliverAppBarState();
}

class _StretchableSliverAppBarState extends State<StretchableSliverAppBar> {
  bool _stretch = true;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      body: CustomScrollView(
        physics: const BouncingScrollPhysics(),
        slivers: <Widget>[
          SliverAppBar(
            stretch: _stretch,
            onStretchTrigger: () async {},
            expandedHeight: 200.0,
            flexibleSpace: const FlexibleSpaceBar(
              title: Text('SliverAppBar'),
              background: FlutterLogo(),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  color: index.isOdd ? Colors.white : Colors.black12,
                  height: 100.0,
                  child: Center(
                    child: Text('$index', textScaleFactor: 5),
                  ),
                );
              },
              childCount: 20,
            ),
          ),
        ],
      ),
    ));
  }
}

The test code:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:test_project/main.dart';

const Offset _kOffset = Offset(0.0, -200.0);

void main() {
  testWidgets('SliverAppbar can be stretched', (WidgetTester tester) async {
    await tester.pumpWidget(
      const StretchableSliverAppBar(),
    );

    expect(find.text('SliverAppBar'), findsOneWidget);
    expect(tester.getBottomLeft(find.text('SliverAppBar')).dy, 184.0);

    await tester.drag(find.text('0'), _kOffset,
        touchSlopY: 0, warnIfMissed: false);
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));
    // Failing to find this text "SliverAppBar"
    expect(find.text('SliverAppBar'), findsOneWidget);
 });
}

And this the error found in the test result

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
  Actual: _TextFinder:<zero widgets with text "SliverAppBar" (ignoring offstage widgets)>
   Which: means none were found but one was expected

When the exception was thrown, this was the stack:
#4      main.<anonymous closure> (file:///D:/Flutter_Projects/test_project/test/widget_test.dart:56:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

This was caught by the test expectation on the following line:
  file:///D:/Flutter_Projects/test_project/test/widget_test.dart line 56
The test description was:
  SliverAppbar can be stretched
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: SliverAppbar can be stretched

✖ SliverAppbar can be stretched

Now, shouldn’t the test be passed?

2

Answers


  1. You can wrap the MaterialApp with a WidgetTester by using the pumpWidget

    import 'package:flutter/material.dart';
    import 'package:flutter_test/flutter_test.dart';
    import 'package:test_project/main.dart';
    
    const Offset _kOffset = Offset(0.0, -200.0);
    
    void main() {
      testWidgets('SliverAppbar can be stretched', (WidgetTester tester) async {
        await tester.pumpWidget(
          MaterialApp(
            home: StretchableSliverAppBar(),
          ),
        );
    
        expect(find.text('SliverAppBar'), findsOneWidget);
        expect(tester.getBottomLeft(find.text('SliverAppBar')).dy, 184.0);
    
        await tester.drag(find.text('0'), _kOffset,
            touchSlopY: 0, warnIfMissed: false);
        await tester.pump();
        await tester.pump(const Duration(milliseconds: 500));
        expect(find.text('SliverAppBar'), findsOneWidget);
     });
    }
    
    Login or Signup to reply.
  2. Based on the error log, it seems that the test is failing because it is unable to find the "SliverAppBar" text widget, which is expected to be present in the widget tree.

    One reason this could be happening is that the widget tree is not being fully built during the test execution. You can try adding an await tester.pumpAndSettle() after the await tester.pump(const Duration(milliseconds: 500)) line to ensure that the widget tree has finished building before the expected statement is executed.

    Another reason could be that the SliverAppBar widget is not being stretched as expected, causing the text widget to disappear from the screen. You can try adding a print statement to check the value of _stretch variable in _StretchableSliverAppBarState class during the test execution to verify that it is being set to true.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search