在ListView中显示多个子项时,如果一个子项不在屏幕上,则无法通过小部件测试找到它。这是一个完整的示例:
main.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);
});
}
该测试失败,但是,如果我将main.dart中的Container
的高度更改为599
,它将起作用。
有人知道为什么会这样吗?是虫子吗?有办法解决吗?
答案 0 :(得分:2)
仅将skipOffstate
设置为false
可能会解决此问题:
expect(find.text("Find me!", skipOffstage: false), findsOneWidget);
此外,您可以使用WidgetTester
方便的ensureVisible方法滚动ListView
并确保查找程序指定的小部件可见。
await tester.ensureVisible(find.text("Find me!", skipOffstage: false));
await tester.pumpAndSettle();
expect(find.text("Find me!"), findsOneWidget);
答案 1 :(得分:1)
测试的行为应与应用程序的行为相同,否则,测试将变得无用(因为您未测试实际行为)。 因此,这不是错误。
您必须在测试内部手动滚动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
答案 2 :(得分:0)
我强烈建议您注意屏幕/拖动运动的“笛卡尔平面”。
让我解释一下:
2.1) 因此:(偏移命令使用笛卡尔“方向”) - 让我们看看: a) 左拖动:偏移(-500.0, 0.0) b) 右拖动:偏移(+500.0, 0.0) c) 向上拖动:偏移(0.0, +500.0) d) 向下拖动:Offset(0.0, -500.0)