为什么TestGesture.moveBy无法在TabBarView中滚动?

时间:2019-06-17 13:04:40

标签: testing flutter

我在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()的输出表明这是因为没有滚动。

我的有状态小部件:

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

}

这是一个错误,还是需要做一些不同的事情才能使TestGesture.moveBy在TabBarView中工作?非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我认为此问题与以下事实有关:拖动结束于可滚动区域之外,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);
  });