許多應用都包含內容列表,從郵件客戶端到音樂應用等等。要使用小部件測試來驗證列表是否包含預期內容,您需要一種方法來滾動列表以搜尋特定專案。

要透過整合測試滾動列表,請使用 WidgetTester 類提供的方法,該類包含在 flutter_test 包中。

在本食譜中,您將瞭解如何滾動專案列表以驗證是否顯示了特定小部件,以及不同方法的優缺點。

本示例將採取以下步驟

  1. 建立一個包含專案列表的應用。
  2. 編寫一個滾動列表的測試。
  3. 執行測試。

1. 建立一個包含專案列表的應用

#

本食譜將構建一個顯示長專案列表的應用。為了讓本食譜專注於測試,請使用 處理長列表 食譜中建立的應用。如果您不確定如何處理長列表,請參閱該食譜以獲得介紹。

在整合測試中,為要互動的小部件新增金鑰(key)。

dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp(items: List<String>.generate(10000, (i) => 'Item $i')));
}

class MyApp extends StatelessWidget {
  final List<String> items;

  const MyApp({super.key, required this.items});

  @override
  Widget build(BuildContext context) {
    const title = 'Long List';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(title: const Text(title)),
        body: ListView.builder(
          // Add a key to the ListView. This makes it possible to
          // find the list and scroll through it in the tests.
          key: const Key('long_list'),
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(
                items[index],
                // Add a key to the Text widget for each item. This makes
                // it possible to look for a particular item in the list
                // and verify that the text is correct
                key: Key('item_${index}_text'),
              ),
            );
          },
        ),
      ),
    );
  }
}

2. 編寫一個滾動列表的測試

#

現在,您可以編寫一個測試了。在此示例中,滾動專案列表並驗證列表中是否存在特定專案。 WidgetTester 類提供了 scrollUntilVisible() 方法,該方法會滾動列表直到特定小部件可見。這很有用,因為列表中專案的高度可能會因裝置而異。

scrollUntilVisible() 方法會反覆滾動專案列表,直到找到所需內容,而不是假設您知道列表中所有專案的高度,或者某個特定小部件在所有裝置上都已渲染。

以下程式碼顯示瞭如何使用 scrollUntilVisible() 方法來搜尋列表中的特定專案。此程式碼位於名為 test/widget_test.dart 的檔案中。

dart

// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:scrolling/main.dart';

void main() {
  testWidgets('finds a deep item in a long list', (tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(
      MyApp(items: List<String>.generate(10000, (i) => 'Item $i')),
    );

    final listFinder = find.byType(Scrollable);
    final itemFinder = find.byKey(const ValueKey('item_50_text'));

    // Scroll until the item to be found appears.
    await tester.scrollUntilVisible(itemFinder, 500.0, scrollable: listFinder);

    // Verify that the item contains the correct text.
    expect(itemFinder, findsOneWidget);
  });
}

3. 執行測試

#

從專案根目錄使用以下命令執行測試:

flutter test test/widget_test.dart