我在TabbarView中有ListView小部件,允许用户滚动浏览每个选项卡的内容。我想测试一些屏幕外的小部件。我按照此操作滚动ListView以将相关小部件显示在屏幕上:
How to find off-screen ListView child in widget tests?
在我将ListView放在TabbarView中之前,这是正常的,然后它失败了。
我在TabbarView中重建了没有ListView的代码,测试通过。将ListView放置在TabbarView中会导致测试失败,原因如下:
'zero widgets with text "bbb" (ignoring offstage widgets)'
debugDumpApp()
output显示这是因为没有滚动。我的状态小部件:
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scroll test'),
),
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
expandedHeight: 100.0,
bottom: TabBar(
controller: _tabController,
tabs: <Widget>[
Tab(
child: Text('Tab one'),
),
Tab(
child: Text('Tab two'),
)
],
),
)
];
},
body: TabBarView(
controller: _tabController,
children: <Widget>[
ListView(
children: <Widget>[
Container(
height: 800.0,
child: Text('aaa'),
),
Text('bbb')
],
),
ListView(
children: <Widget>[
Container(
height: 800.0,
child: Text('ccc'),
),
Text('ddd')
],
),
],
)
)
);
}
}
我的测试:
void main() {
Widget buildTestableWidget(Widget widget) {
return new MediaQuery(
data: new MediaQueryData(), child: new MaterialApp(home: widget));
}
Home home = Home();
testWidgets('scroll test', (WidgetTester tester) async {
await tester.pumpWidget(buildTestableWidget(home));
expect(find.text('aaa'), findsOneWidget);
expect(find.text('bbb'), findsNothing);
final Offset point = tester.getCenter(find.text("aaa"));
final gesture = await tester.startGesture(point);
await gesture.moveBy(const Offset(0.0, -400.0));
await tester.pump();
expect(find.text('bbb'), findsOneWidget);
});
}
这是一个bug,还是需要做一些不同的事情来获取testGesture.moveby以在TabbarView中工作?非常感谢你的帮助。
最佳答案
我认为这个问题与拖动结束在可滚动区域之外的事实有关,WidgetTester
有一个名为dragFrom的方法,它为您处理该场景。
testWidgets('scroll test', (WidgetTester tester) async {
await tester.pumpWidget(buildTestableWidget(home));
expect(find.text('aaa'), findsOneWidget);
expect(find.text('bbb'), findsNothing);
final Offset point = tester.getCenter(find.text("aaa"));
await tester.dragFrom(point, Offset(0.0, -400.0));
await tester.pump();
expect(find.text('bbb'), findsOneWidget);
});