[英]How to test the order of multiple list items in Flutter / Dart?
介绍
我们有一个名为 OrganizationList 的ListView
,其中包含每个项目的ListTile
小部件。 我们使用Text
小部件在ListTile
中显示组织名称。
我们想测试组织名称是否以正确的顺序正确显示。
我们目前的解决方案
我们有以下断言:
var organizationA = find
.descendant(
of: find.byType(OrganizationList),
matching: find.byKey(
Key('0'),
),
)
.evaluate()
.first
.widget as Text;
expect(textOrganization.data, 'organization-a');
var organizationB = find
.descendant(
of: find.byType(OrganizationList),
matching: find.byKey(
Key('1'),
),
)
.evaluate()
.first
.widget as Text;
expect(textOrganization.data, 'organization-b');
如果为列表项显示正确的 label,这感觉是一种非常麻烦的测试方法。 但是我找不到更优雅的方法。
问题
Flutter / Dart 中断言列表项的内容和所有项的顺序的更优雅的方法是什么?
使用我的解决方案,您可以检查特定 position 的 ListItemWidget 和文本是否可见(或不可见):
void checkPosition(int index, SomeObj obj, {bool isOnPosition = true}) {
final listItemFinder = find.byType(ListItemWidget);
final listItem = listItemFinder.evaluate().isEmpty
? null
: listItemFinder.at(index);
if (listItem == null) {
if (isOnPosition) {
fail('List not found');
}
return;
}
final positionText = find.text(obj.text);
expect(find.descendant(of: listItem, matching: positionText),
isOnPosition ? findsOneWidget : findsNothing);
}
从 List 获取元素并进行验证的最简单方法是widgetList
,它给出了我们提供的任何数据类型的元素列表。
样品测试:
问题:验证 List 中的第二项
const List<String> listString = [
"Ac",
"Fuel Sensor",
"Power",
"Panic",
"Camera",
"Relay",
"Duty Button",
"Other"
];
测试:
testWidgets('Listview item verify', (WidgetTester tester) async {
await tester.pumpWidget(ListViewApp());
/// Verify OrganizationIte sequence to get and verify title.
OrganizationItem item = tester
.widgetList<OrganizationItem>(find.byType(OrganizationItem))
.elementAt(2);
String data = item.title;
expect("Power", data);
});
应用代码:
class ListViewApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Checked Listview',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: MyHomePage(title: 'Flutter Checked Listview'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> _list = [];
@override
void initState() {
setState(() {
for (int i = 0; i < listString.length; i++) {
_list.add('${listString[i]}');
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Listview Sample'),
),
body: ListView.builder(
itemBuilder: (_, int index) {
return OrganizationItem(
title: _list[index],
);
},
itemCount: _list.length,
),
);
}
}
class OrganizationItem extends StatelessWidget {
final String title;
const OrganizationItem({Key? key, required this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(this.title),
);
}
}
尝试for
循环:
// This is for saving a reference to the ListTile from the previous iteration
ListTile? previousListTile;
for (int j = 0; j < aListOfModels.length; j++) {
final organizationA = find.descendant(
of: find.byType(OrganizationList),
matching: find.byKey(
Key('0'),
),
);
// This is important to show the invisible late elements
await widgetTester.scrollUntilVisible(organizationA, tryToFindTheSuitableDelta);
// I suppose that organizationA finds a ListTile widget
ListTile currentListTile = widgetTester.widget<ListTile>(organizationA);
/*
Make your expectations about the content as you like
....
...
*/
// To expect about the order, do the following:
final listTileWidgetList = widgetTester
.widgetList<ListTile>(find.byType(ListTile))
.toList();
if (j > 0) {
// Expect that the currentListTile is the first next ListTile of the previousListTile
expect(listTileWidgetList.indexOf(currentListTile),
equals(listTileWidgetList.indexOf(previousListTile!) + 1));
}
// To allow you to make your expectation about the order in the next iteration
previousListTile = currentListTile;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.