Testing Flutter apps翻訳-クリック、ドラッグ、入力テキスト

8508 ワード

テキストリンク:https://juejin.im/post/5cbd885f6fb9a032341647fc
翻訳ホームページ
多くのビルドのWidgetは、情報を表示するだけでなく、ユーザーのインタラクションにも応答します.クリック可能なボタン、画面でコントロールをドラッグしたり、テキストボックスにテキストを入力したりします.
それらのインタラクションをテストするためには、テスト環境でそれらをシミュレートする方法が必要です.そのためには、flutter_testクラスライブラリのWidgetTesterクラスを使用する必要があります.
このWidgetTesterは、入力テキスト、クリック、ドラッグの方法を提供します.
  • enterText
  • tap
  • drag

  • 多くの場合、ユーザーインタラクションはappの状態を更新します.テスト環境では、ステータスが変更された後、Flutterは自動的にWidgetsを再構築しません.我々のWidgetツリーがユーザインタラクションをシミュレートした後に再buildされることを保証するために、WidgetTesterが提供するpumpまたはpumpAndSettleメソッドを呼び出す必要があります.
    手順:
  • は、
  • をテストするためのWidgetを作成する.
  • 入力ボックスにテキスト
  • を入力する.
  • ボタンをクリックするとtodo
  • が追加されることを確認します.
  • スライド削除todo
  • を確保する.

    1.テスト用のWidgetを作成する


    この例では、基礎的なtodo appを作成します.テストが必要な主な機能は3つあります.
  • TextFieldにテキスト
  • を入力
  • FloatingActionButtonボタンをクリックtodoリストにテキスト
  • を追加
  • スライドリストからitem
  • を削除
    テストに焦点を当てるために、この例はtodo appを構築するための詳細なインタフェースを提供しない.appの構築方法についてもっと勉強したい場合は、次の関連記事を参照してください.
  • Create and style a text field
  • Handling Taps
  • Create a basic list
  • Implement Swipe to Dismiss
  • class TodoList extends StatefulWidget {
      @override
      _TodoListState createState() => _TodoListState();
    }
    
    class _TodoListState extends State {
      static const _appTitle = 'Todo List';
      final todos = [];
      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.入力ボックスにテキストを入力


    今私たちはtodo appを持っていて、私たちは私たちのテストを書くことができます!この例では、入力テキストからTextFieldに開始します.
    私たちはこのようにして任務を遂行することができます.
  • テスト環境build 1つのWidget
  • WidgetTesterenterText
  • を用いる.
    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テスト紹介
  • Finderを使用してchild widget
  • を検索

    3.ボタンをクリックするとtodoが追加されることを確認する

    TextFieldにテキストを入力した後、FloatingActionButtonをクリックするとitemがリストに追加されます.
    これらの手順には、次の3つのステップがあります.
  • tapメソッドを使用してボタンをクリックします.
  • ステータスが変更された後、pumpメソッドを使用してビルドWidgetを再構築します.
  • itemが画面のリストに表示されることを確認します.
  • 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);
    });
    

    3.スライドリストからitemを削除


    最後に、スライドしてtodoを削除した後、リストから削除できることを確認します.これには、次の3つのステップが含まれます.
  • は、dragの方法を使用してスライド削除動作を実行する.
  • pumpAndSettleメソッドを使用して、dismissアニメーションが完了するまでWidgetツリーを絶えず再構築します.
  • itemが画面から消えることを確認します.
  • 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 {
      static const _appTitle = 'Todo List';
      final todos = [];
      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),
            ),
          ),
        );
      }
    }