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
You can wrap the MaterialApp with a WidgetTester by using the pumpWidget
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 theawait 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.