这个flutter_test包提供了以下用于测试Widget的工具:
WidgetTester:该工具允许我们在测试环境里build Widget并与之交互。
使用testWidgets函数。这个函数将自动对每个测试用例创建一个WidgetTester,并用于替代普通的test函数。
Finder classes:该工具允许我们在测试环境里查找Widget。
Widget Matcher:一些常量,帮助我们验证在测试环境里是否找到一个或者多个Widget。
如果上面的内容听不懂的话,没关系,让我们通过一些例子来将上面的碎片信息串联到一起。
步骤:
添加flutter_test依赖。
创建一个Widget用来测试。
创建一个testWidgets测试方法。
使用WidgetTesterbuild一个Widget
使用Finder搜索我们的Widget。
使用Matcher验证我们的Widget是否工作正常。
1. 添加flutter_test依赖。
在我们开始写测试之前,我们需要在pubspec.yaml文件的dev_dependencies行下面添加flutter_test包。如果你通过命令行或者编译器创建的Flutter项目,那么该依赖已经添加好了。
dev_dependencies: flutter_test: sdk: flutter |
2. 创建一个Widget用来测试。
下一步,我们需要创建一个能让我们测试的Widget。在这个例子里,我们创建了显示一个标题和一条信息的Widget。
class MyWidget extends StatelessWidget { final String title; final String message; const MyWidget({ Key key, @required this.title, @required this.message, }) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Text(message), ), ), ); } } |
3. 创建一个testWidgets测试方法
现在我们有了一个可以用来测试的Widget,我们可以编写我们第一个测试用例了!我们将会使用flutter_test包提供的testWidgets函数完成一个测试用例。这个testWidgets函数将会允许我们定义一个Widget测试用例并创建一个WidgetTester给我们使用。
我们的测试将会验证MyWidget类是否正常显示给定的标题和信息。
void main() { // Define a test. The TestWidgets function will also provide a WidgetTester // for us to work with. The WidgetTester will allow us to build and interact // with Widgets in the test environment. testWidgets('MyWidget has a title and message', (WidgetTester tester) async { // Test code will go here! }); } |
4. 使用WidgetTesterbuild一个Widget
下一步,我们将会在测试环境里build我们的MyWidget类。为了这么做,我们将使用WidgetTester提供的pumpWidget方法。这个pumpWidget方法将会build和渲染我们提供的Widget。
在这个示例里,我们将会创建一个显示标题“T”和消息“M”的MyWidget实例。
void main() { testWidgets('MyWidget has a title and message', (WidgetTester tester) async { // Create the Widget tell the tester to build it await tester.pumpWidget(MyWidget(title: 'T', message: 'M')); }); } |
备注:
第一次调用pumpWidget之后,WidgetTester提供了重新创建相同Widget的其他方式。如果你使用StatefulWidget或者动画,这将会非常有用。
例如,如果我们点击一个按钮,并且这个按钮调用了setState方法,Flutter不会在测试环境里rebuild你的Widget。我们需要使用下面的方法之一来告诉Flutter再一次build我们的Widget。
tester.pump()
在一个给定的时间以后rebuild你的Widget。
tester.pumpAndSettle()
在给定的时间不断重复调用pump方法直到不再有任何绘制任务。一般用于等待所有动画完成。
这些方法提供了比build生命周期更细粒度的控制,这在测试的时候特别有用。
5. 使用Finder搜索我们的Widget。
现在我们已经在测试环境构建了我们的Widget,我们想要通过使用Finder在Widget树里搜索我们的title和messageWidget。这将允许我们验证是否正确显示了那些Widget!
在这个例子里,我们将会使用flutter_test包提供的顶级find方法去创建我们的Finder类。因为我们知道我们在寻找Text widget,所以我们可以使用find.text方法。
有关Finder类的更多信息,请查看在Widget测试里查找Widget。
void main() { testWidgets('MyWidget has a title and message', (WidgetTester tester) async { await tester.pumpWidget(MyWidget(title: 'T', message: 'M')); // Create our Finders final titleFinder = find.text('T'); final messageFinder = find.text('M'); }); } |
6. 使用Matcher验证我们的Widget是否工作正常。
最后,我们可以使用flutter_test包提供的Matcher常量来验证title和message Text Widgets是否出现在屏幕。
Matcher类是test包的核心部分,并且提供了通用的方式去验证给定的值是否符合我们的期望。
在这个例子里,我们想要我们的Widgets只在屏幕出现一次。因此,我们可以使用findsOneWidget这个Matcher。
void main() { testWidgets('MyWidget has a title and message', (WidgetTester tester) async { await tester.pumpWidget(MyWidget(title: 'T', message: 'M')); final titleFinder = find.text('T'); final messageFinder = find.text('M'); // Use the `findsOneWidget` matcher provided by flutter_test to verify our // Text Widgets appear exactly once in the Widget tree expect(titleFinder, findsOneWidget); expect(messageFinder, findsOneWidget); }); } |
额外的Matcher:
在findsOneWidget以外,flutter_test为常见用例提供了额外的Matcher:
findsNothing
验证没有Widget被找到。
findsWidgets
验证一个或者多个Widget被找到。
findsNWidgets
验证指定数量的Widget被找到。
完整示例:
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { // Define a test. The TestWidgets function will also provide a WidgetTester // for us to work with. The WidgetTester will allow us to build and interact // with Widgets in the test environment. testWidgets('MyWidget has a title and message', (WidgetTester tester) async { // Create the Widget tell the tester to build it await tester.pumpWidget(MyWidget(title: 'T', message: 'M')); // Create our Finders final titleFinder = find.text('T'); final messageFinder = find.text('M'); // Use the `findsOneWidget` matcher provided by flutter_test to verify our // Text Widgets appear exactly once in the Widget tree expect(titleFinder, findsOneWidget); expect(messageFinder, findsOneWidget); }); } class MyWidget extends StatelessWidget { final String title; final String message; const MyWidget({ Key key, @required this.title, @required this.message, }) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Text(message), ), ), ); } } |
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。