(译)点击,拖拽以及输入文本

栏目: ASP.NET · 发布时间: 5年前

内容简介:我们构建的许多widget不仅显示信息,还要响应用户交互。这包括用户可以点击的按钮,在屏幕上拖动条目或在TextField中输入文本。为了测试这些交互,我们需要一种在测试环境中模拟它们的方法。为此,我们可以使用

原文链接

我们构建的许多widget不仅显示信息,还要响应用户交互。这包括用户可以点击的按钮,在屏幕上拖动条目或在TextField中输入文本。

为了测试这些交互,我们需要一种在测试环境中模拟它们的方法。为此,我们可以使用 flutter_test 库提供的 WidgetTester 类。

WidgetTester 提供了输入文本,点击和拖动的方法。

  • enterText
  • tap
  • darg

在许多情况下,用户交互将更新我们的应用程序的状态。在测试环境中,当状态更改时,Flutter不会自动重建widget。为了确保在模拟用户交互之后重建我们的Widget树,我们必须调用 WidgetTester 提供的 pumppumpAndSettle 方法。

路径

  1. 创建一个要测试的widget
  2. 在文本字段中输入文本
  3. 确保点击按钮添加待办事项
  4. 确保滑动删除会删除待办事项

1.创建一个要测试的widget

对于此示例,我们将创建一个基本的待办事项应用程序。它将有三个我们想要测试的主要功能:

  1. 在TextField中输入文本
  2. 点击FloatingActionButton会将文本添加到待办事项列表中
  3. 滑动删除会从列表中删除该条目

为了将重点放在测试上,此配方将不提供有关如何构建待办事项应用程序的详细指南。要了解有关如何构建此应用程序的更多信息,请参阅相关配方:

class TodoList extends StatefulWidget {
  @override
  _TodoListState createState() => _TodoListState();
}

class _TodoListState extends State<TodoList> {
  static const _appTitle = 'Todo List';
  final todos = <String>[];
  final controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(_appTitle),
        ),
        body: Column(
          children: [
            TextField(
              controller: controller,
            ),
            Expanded(
              child: ListView.builder(
                itemCount: todos.length,
                itemBuilder: (BuildContext context, int index) {
                  final todo = todos[index];

                  return Dismissible(
                    key: Key('$todo$index'),
                    onDismissed: (direction) => todos.removeAt(index),
                    child: ListTile(title: Text(todo)),
                    background: Container(color: Colors.red),
                  );
                },
              ),
            ),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              todos.add(controller.text);
              controller.clear();
            });
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

2.在 text field 中输入文本

现在我们有了一个todo应用程序,我们就可以开始编写测试了!在这种情况下,我们首先在 TextField 中输入文本。

我们可以通过以下方式完成此任务

  1. 在测试环境中构建Widget
  2. 使用 WidgetTester 中的 enterText 方法
testWidgets('Add and remove a todo', (WidgetTester tester) async {
  // Build the Widget
  await tester.pumpWidget(TodoList());

  // Enter 'hi' into the TextField
  await tester.enterText(find.byType(TextField), 'hi');
});

注意:此配方基于之前的Widget测试配方。要了解Widget测试的核心概念,请参阅以下配方:

3.确保点击按钮添加待办事项

在我们将文本输入TextField之后,我们要确保点击FloatingActionButton将该项添加到列表中。

这将涉及三个步骤:

  1. 使用tap方法点击添加按钮
  2. 使用pump方法更改状态后重建Widget
  3. 确保列表项显示在页面上
testWidgets('Add and remove a todo', (WidgetTester tester) async {
  // Enter text code...

  // Tap the add button
  await tester.tap(find.byType(FloatingActionButton));

  // Rebuild the Widget after the state has changed
  await tester.pump();

  // Expect to find the item on screen
  expect(find.text('hi'), findsOneWidget);
});

4. 确保滑动删除会删除待办事项

最后,我们可以确保对todo项执行滑动删除操作会将其从列表中删除。这将涉及三个步骤:

  • 使用 drag 方法执行滑动到解除操作。
  • 使用 pumpAndSettle 方法不断重建我们的Widget树,直到dismiss动画完成。
  • 确保屏幕上不再显示该条目。
testWidgets('Add and remove a todo', (WidgetTester tester) async {
  // Enter text and add the item...

  // Swipe the item to dismiss it
  await tester.drag(find.byType(Dismissible), Offset(500.0, 0.0));

  // Build the Widget until the dismiss animation ends
  await tester.pumpAndSettle();

  // Ensure the item is no longer on screen
  expect(find.text('hi'), findsNothing);
});

完整代码

一旦我们完成了这些步骤,我们应该有了带有测试的一个工作的应用程序,其测试部分能确保它正常工作!

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

void main() {
  testWidgets('Add and remove a todo', (WidgetTester tester) async {
    // Build the Widget
    await tester.pumpWidget(TodoList());

    // Enter 'hi' into the TextField
    await tester.enterText(find.byType(TextField), 'hi');

    // Tap the add button
    await tester.tap(find.byType(FloatingActionButton));

    // Rebuild the Widget with the new item
    await tester.pump();

    // Expect to find the item on screen
    expect(find.text('hi'), findsOneWidget);

    // Swipe the item to dismiss it
    await tester.drag(find.byType(Dismissible), Offset(500.0, 0.0));

    // Build the Widget until the dismiss animation ends
    await tester.pumpAndSettle();

    // Ensure the item is no longer on screen
    expect(find.text('hi'), findsNothing);
  });
}

class TodoList extends StatefulWidget {
  @override
  _TodoListState createState() => _TodoListState();
}

class _TodoListState extends State<TodoList> {
  static const _appTitle = 'Todo List';
  final todos = <String>[];
  final controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(_appTitle),
        ),
        body: Column(
          children: [
            TextField(
              controller: controller,
            ),
            Expanded(
              child: ListView.builder(
                itemCount: todos.length,
                itemBuilder: (BuildContext context, int index) {
                  final todo = todos[index];

                  return Dismissible(
                    key: Key('$todo$index'),
                    onDismissed: (direction) => todos.removeAt(index),
                    child: ListTile(title: Text(todo)),
                    background: Container(color: Colors.red),
                  );
                },
              ),
            ),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              todos.add(controller.text);
              controller.clear();
            });
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

微服务设计

微服务设计

[英] Sam Newman / 崔力强、张 骏 / 人民邮电出版社 / 2016-5 / 69.00元

本书全面介绍了微服务的建模、集成、测试、部署和监控,通过一个虚构的公司讲解了如何建立微服务架构。主要内容包括认识微服务在保证系统设计与组织目标统一上的重要性,学会把服务集成到已有系统中,采用递增手段拆分单块大型应用,通过持续集成部署微服务,等等。一起来看看 《微服务设计》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具