Testing Flutter apps翻译-Widget测试介绍

翻译首页bash

单元测试的介绍里,咱们学习到了如何使用test包测试Dart类,为了测试Widget类,咱们须要一些由flutter test包提供的额外工具,这些工具随Flutter SDK发布。app

这个flutter_test包提供了如下用于测试Widget的工具:less

  • WidgetTester:该工具容许咱们在测试环境里build Widget并与之交互。
  • 使用testWidgets函数。这个函数将自动对每一个测试用例建立一个WidgetTester,并用于替代普通的test函数。
  • Finder classes:该工具容许咱们在测试环境里查找Widget。
  • Widget Matcher:一些常量,帮助咱们验证在测试环境里是否找到一个或者多个Widget。

若是上面的内容听不懂的话,不要紧,让咱们经过一些例子来将上面的碎片信息串联到一块儿。async

步骤:ide

  1. 添加flutter_test依赖。
  2. 建立一个Widget用来测试。
  3. 建立一个testWidgets测试方法。
  4. 使用WidgetTesterbuild一个Widget
  5. 使用Finder搜索咱们的Widget。
  6. 使用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给咱们使用。post

咱们的测试将会验证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树里搜索咱们的titlemessageWidget。这将容许咱们验证是否正确显示了那些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),
        ),
      ),
    );
  }
}
复制代码
相关文章
相关标签/搜索