翻译首页html
许多应用程序都包含列表,从email应用程序到音乐应用程序等等。咱们指望使用集成测试验证列表中的内容,咱们须要一个方法去滚动列表来查找特定的item。api
为了使用集成测试滚动列表,咱们可使用FlutterDriver
类提供的方法, 该类包含在 flutter_driver
包里:bash
在文本里,咱们将会学习到如何滚动列表并验证列表里显示的一个特定的Widget,而且讨论不一样方法的利弊。 若是你刚刚开始集成测试,能够阅读集成测试介绍 获取更多信息。app
步骤:less
在本文里,咱们将会build一个app来显示一个长列表。为了将本文重点放在测试上,咱们使用Working with long lists文章里建立的app。若是你不知道如何处理列表,请自行查看相关介绍。async
像咱们在集成测试介绍 里作的那样,咱们也将添加key给集成测试里须要和咱们交互的widget。ide
import 'package:flutter/foundation.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;
MyApp({Key key, @required this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
final title = 'Long List';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView.builder(
// Add a key to the ListView. This allows us to find the list and
// scroll through it in our tests
key: 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 allows
// us to look for a particular item in the list and verify the
// text is correct
key: Key('item_${index}_text'),
),
);
},
),
),
);
}
}
复制代码
下一步,咱们须要建立咱们应用程序的可检测版本。这个代码位于test_driver/app.dart
文件里。post
import 'package:flutter_driver/driver_extension.dart';
import 'package:scrollable_app/main.dart' as app;
void main() {
// This line enables the extension
enableFlutterDriverExtension();
// Call the `main()` function of your app or call `runApp` with any widget you
// are interested in testing.
app.main();
}
复制代码
如今,咱们能够编写咱们的测试了!在这个例子里,咱们须要滚动列表并验证一个特定的item是否存在于列表里。这个FlutterDriver
类提供了3个滚动列表的方法:学习
scroll
方法容许咱们根据给定的数量去滚动列表。scrollIntoView
方法能够找到已经被渲染的特定Widget,而后将它滚动到可见区域。某些Widget,好比ListView.builder
,只有将要显示的时候才会去渲染item。scrollUntilVisible
方法滚动列表直到特定Widget被显示(译者注:通过个人测试发现scrollIntoView
和scrollUntilVisible
的区别是scrollIntoView
查找的是已经渲染过的item,若是这个item尚未被渲染过的话用scrollIntoView
就找不到这个item)。虽然这三种方法均可以做用于特定的用例,可是scrollUntilVisible
是最常使用的,为何呢?测试
scroll
方法,咱们可能不正确的假设列表中item的高度。这将致使滚动的太多或者太少。scrollIntoView
方法,咱们可能假定该Widget已经被实例化而且被渲染。为了验证咱们的app可工做在更多的设备里,咱们须要针对不一样屏幕大小的设备运行咱们的集成测试。由于ListView.builder
只有将要显示的时候才会去渲染item,因此一个特定的Widget是否能被渲染取决于设备屏幕的大小。因此,咱们既不须要知道列表中全部item的高度,也不须要知道一个特定的Widget何时在不一样的设备被渲染,咱们只须要调用scrollUntilVisible
方法反复滚动列表直到找到咱们须要的那个item!
让咱们来看看如何经过scrollUntilVisible
方法去查找列表中的特定Widget!这些代码咱们放到了test_driver/app_test.dart
文件里。
// Imports the Flutter Driver API
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
void main() {
group('Scrollable App', () {
FlutterDriver driver;
// Connect to the Flutter driver before running any tests
setUpAll(() async {
driver = await FlutterDriver.connect();
});
// Close the connection to the driver after the tests have completed
tearDownAll(() async {
if (driver != null) {
await driver.close();
}
});
test('verifies the list contains a specific item', () async {
// Create two SerializableFinders. We will use these to locate specific
// Widgets displayed by the app. The names provided to the byValueKey
// method correspond to the Keys we provided to our Widgets in step 1.
final listFinder = find.byValueKey('long_list');
final itemFinder = find.byValueKey('item_50_text');
await driver.scrollUntilVisible(
// Scroll through this list
listFinder,
// Until we find this item
itemFinder,
// In order to scroll down the list, we need to provide a negative
// value to dyScroll. Ensure this value is a small enough increment to
// scroll the item into view without potentially scrolling past it.
//
// If you need to scroll through horizontal lists, provide a dxScroll
// argument instead
dyScroll: -300.0,
);
// Verify the item contains the correct text
expect(
await driver.getText(itemFinder),
'Item 50',
);
});
});
}
复制代码
最后,咱们能够在项目的根目录里使用下面的命令运行测试:
flutter drive --target=test_driver/app.dart
复制代码