繁体   English   中英

如何测试Flutter / Dart中多个列表项的顺序?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM