8

在 ListView 中显示多个子项时,如果一个子项不在屏幕上,则小部件测试无法找到它。这是一个完整的例子:

主要.dart

import 'package:flutter/material.dart';

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Scaffold(body: Test()));
  }
}

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Container(
          height: 600,
          color: Colors.red,
        ),
        Text("Find me!"),
      ],
    );
  }
}

main_test.dart

import 'package:flutter_app/main.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets("Find text", (WidgetTester tester) async {
    final testableWidget = App();

    await tester.pumpWidget(testableWidget);

    expect(find.text("Find me!"), findsOneWidget);
  });
}

Container该测试失败,但是如果我将main.dart 中的高度更改为599它可以工作。

有谁知道为什么会这样?它是一个错误吗?有办法解决吗?

4

4 回答 4

8

测试应该像您的应用程序那样运行,否则,您的测试将变得毫无用处(因为您没有测试真正的行为)。因此,这不是错误。

您必须手动滚动ListView测试内部以使其加载更多小部件。

这可以使用tester

final gesture = await tester.startGesture(Offset.zero /* THe position of your listview */ );
// Manual scroll
await gesture.moveBy(const Offset(0, 100));

await tester.pump(); // flush the widget tree 
于 2019-02-12T14:18:24.047 回答
7

在 Finder 中设置skipOffstate为另一种方法。false尝试这个:

expect(find.text("Find me!", skipOffstage: false), findsOneWidget);
于 2020-09-25T08:51:37.410 回答
0

我强烈建议您注意屏幕/拖动运动的“笛卡尔平面”。

让我解释:

  1. 您应该使用: await tester.drag(keyCartItemProduct1, Offset(-500.0, 0.0));
  2. 但是,您的“偏移”命令必须遵循与拖动相同的“笛卡尔方向”。

2.1)因此:(命令偏移使用笛卡尔'方向')-让我们看看:a)左拖动:偏移(-500.0,0.0)b)右拖动:偏移(+500.0,0.0)c)向上拖动:偏移(0.0 , +500.0) d) 向下拖动:偏移量(0.0, -500.0)

于 2021-01-13T22:50:31.257 回答
0

dragUntilVisible有助于滚动 Listview 或 SingleChildScrollView 以滚动到预期的小部件可见

     final expectedWidget = find.byText("Find me!");

      await tester.dragUntilVisible(
          expectedWidget, // what you want to find
          find.byType(ListView),
          // widget you want to scroll
          const Offset(0, 500), // delta to move
          duration: Duration(seconds: 2));
于 2022-02-16T12:10:01.867 回答