Flutter 小部件与 Flutter 驱动程序

Posted

技术标签:

【中文标题】Flutter 小部件与 Flutter 驱动程序【英文标题】:Flutter widget vs Flutter driver 【发布时间】:2020-10-19 11:20:57 【问题描述】:

我正在为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 测试通过,它可能会在所有设备上通过。但在我的应用中,我有更复杂的小部件和它们之间的交互,我希望能够在 androidios 上启动测试。

我尝试使用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 教程解释了如何通过 Text 检索对象,这将有助于检查 Text 是否存在,但例如是否可以检查 Container 颜色是否为红色? Widget 和 Integration 测试之间的界限在哪里?

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

【问题讨论】:

您无法在驱动程序测试中读取小部件的属性 我就是这么想的。但是,我们能真正测试什么?存在小部件,但不存在它们的内容? 您可以验证是否有匹配的文本。文本字段也有文本 是的,这是一个例子。我可以通过检索文本来测试它。但是如果我想测试另一个属性怎么办。如果我想检查在特定情况下是否启用了 TextField 怎么办? TextField 有一个 enabled 属性,我可以通过 Widget 测试轻松检查,但是如何使用 Flutter 驱动程序(或其他框架)执行设备测试来检查此属性? 【参考方案1】:

如果有人感兴趣:

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

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

为了在真实设备(Android 或 iOS)上对其进行测试,我使用了here 可用的integration_test 包(以前的e2e 包),它将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 驱动编写更复杂的场景来测试整个应用程序。

【讨论】:

感谢您的信息!刚开始学习Flutter的集成测试,才知道现在推荐integration_test这个包。但我不确定integration_testflutter_driver 之间有什么区别。你的经历让我明白了这一点。【参考方案2】:

我认为颤振小部件和颤振驱动程序之间存在差异。其中,flutter widgets 用于小部件测试,flutter driver 用于集成测试。从实际的角度来看,我不确定这意味着什么,但我认为集成测试更容易对用户进行的应用程序交互进行测试,因为与小部件测试相比,集成测试在实际设备上运行。如果我找到更多相关信息会更新。

【讨论】:

以上是关于Flutter 小部件与 Flutter 驱动程序的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - 如何对齐(小部件)孙小部件与孩子相同

在 Flutter 中使用 BLoC - 在有状态小部件与无状态小部件中的使用

根据 Flutter 中的选定类别为小部件元素分配不同的颜色

在 Flutter 中使用 Flutter Driver 对 OTPTextField 小部件进行集成测试

Flutter ListView 与不同的小部件和列表项

在 Flutter 中只让一个小部件漂浮在键盘上方