Flutter 小部件 vs Flutter 驱动程序

标签 flutter flutter-test flutterdriver

我正在为用 Flutter 编写的移动应用程序编写测试。 我关注了this Flutter Cookbook关于测试 Flutter 应用程序,学习如何编写小部件和集成测试。

本教程非常有效,但我仍然坚持自己的集成测试。

为简化起见,假设我有一个仅包含 TextField 的应用:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'MyAppp',
      home: Scaffold(
        body: Center(child: TextField()),
      ),
    );
  }
}

我想为此应用编写测试。例如,我想测试以下场景:

  • 打开应用
  • 检查 TextField 是否为空
  • 选择TextField
  • 输入“你好,世界!”
  • 检查 TextField 是否包含“hello, world!”

我编写了以下 Widget 测试,效果很好:

void main() {
  testWidgets('TextField behavior', (WidgetTester tester) async {
    // Create app
    await tester.pumpWidget(MyApp());

    // Find TextField, check there is 1
    final textFieldFinder = find.byType(TextField);
    expect(textFieldFinder, findsOneWidget);

    // Retrieve TextField Widget from Finder
    TextField textField = tester.widget(textFieldFinder);

    // Check TextField is empty
    expect(textField.controller.text, equals(""));

    // Enter text
    await tester.enterText(textFieldFinder, "hello, world!");

    // Check TextField contains text
    expect(textField.controller.text, equals("hello, world!"));
  });
}

这个测试通过了,但我想写一个集成测试,或多或少做同样的事情,以便能够在真实设备上测试它。 实际上,如果此 Widget 测试通过,它可能会在所有设备上通过。但在我的应用程序中,我有更复杂的小部件和它们之间的交互,我希望能够在 Android 和 iOS 上启动测试。

我尝试使用 Flutter driver 编写集成测试,但我没有在文档和示例中找到我想要的东西。

如何检查 Widget 属性,以验证我的应用程序是否按预期运行?

我写了下面的例子:

import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';

void main() {
  group('TextField', () {
    final textFieldFinder = find.byType('TextField');

    FlutterDriver driver;

    setUpAll(() async {
      driver = await FlutterDriver.connect();
    });

    tearDownAll(() async {
      if (driver != null) {
        driver.close();
      }
    });

    test('TextField behavior', () async {
      // ??? how to check that the TextField is empty

      await driver.tap(textFieldFinder);
      await driver.enterText("hello, world!");

      // ??? how to check that the TextField contains hello, world!
    });
  });
}

Flutter Cookbook 教程解释了如何通过文本检索对象,这将有助于检查文本是否存在,但例如是否可以检查容器颜色是否为红色? Widget 和 Integration 测试之间的界限在哪里?

编写 Widget 测试非常简单,但我没有找到很多关于如何使用 Flutter 驱动程序编写更复杂的集成测试的示例或文档。

最佳答案

如果有人感兴趣:

为了能够测试我想要的东西(不仅是小部件的存在,还有它们的状态、它们的属性......)测试驱动程序对我来说还不够。

我在我的项目中所做的,是使用 flutter_test 编写 widget 测试并检查我想要的属性。

为了在真实设备(Android 或 iOS)上测试它,我使用了可用的 integration_test 包(以前的 e2e 包)here ,它将 flutter_test 结果调整为与 flutter drive 兼容的格式。

要使用 integration_test,请将此行添加到小部件测试的主体中:

IntegrationTestWidgetsFlutterBinding.ensureInitialized();

然后在您的 test_driver 文件夹中创建一个文件(例如 integration_test.dart),内容如下:

import 'package:integration_test/integration_test_driver.dart';

Future<void> main() => integrationDriver();

然后您可以通过运行以下命令来启动这些驱动程序测试:

flutter drive \
  --driver=test_driver/integration_test.dart \
  --target=test/widget_test/widget_test.dart

将您的小部件测试写入文件 test/widget_test/widget_test.dart

这对我很有帮助,因为一些小部件在 Android 和 iOS 上的行为不同。

今天我同时使用了 flutter_test(在带有 integration_test 的真实设备上启动)和真实的 flutter_driver 测试:

  • 我编写小部件测试来检查单个小部件或单个页面,
  • 我使用 flutter driver 编写更复杂的场景来测试整个应用程序。

关于Flutter 小部件 vs Flutter 驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62635696/

相关文章:

flutter - 是否可以在 flutter 中提供启动随机数序列的种子?

flutter - Flutter 项目中的 build.yaml 文件在哪里?

firebase - 无法将FLUTTER参数分配给参数类型

Flutter 驱动程序 - 在屏幕外的字段中输入文本

FlutterDriver - 如何关闭 showDialog

command-line-arguments - Flutter Driver - 我们可以将命令行参数传递给 Flutter 驱动程序测试吗

Flutter:删除生成的文件

dart - Flutter 处理来自其他小部件的输入文本字段

flutter - 如何为 cupertino 数据选择器运行 flutter widget 测试?

没有日期的 Flutter DatePicker。使用 Future<DateTime?> showDatePicker。插件限制