Flutter Widget 与 Flutter Driver

3

我正在为一个使用 Flutter 编写的移动应用编写测试。我遵循了这个 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
  • 输入“hello, world!”
  • 检查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!"));
  });
}

这个测试通过了,但我想写一个集成测试,做更多或更少相同的事情,以便能够在真实设备上测试它。 确实,如果这个小部件测试通过了,它很可能会在所有设备上都通过。 但是在我的应用程序中,我有更复杂的小部件和它们之间的交互,我希望能够在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教程解释了如何通过其文本检索对象,这有助于检查文本是否存在,但例如,是否可以检查Container的颜色是否为红色?Widget和集成测试之间的界限在哪里?

编写Widget测试非常直接,但我没有找到许多关于如何使用Flutter driver编写更复杂的集成测试的示例或文档。


你无法在驱动测试中读取小部件的属性。 - Rémi Rousselet
这正是我所想的...但是,我们真正可以测试什么呢?小部件的存在,但不包括它们的内容? - Lucie
你可以验证是否有匹配的文本。文本字段也有文本。 - Rémi Rousselet
是的,当然。这只是一个例子。我可以通过检索文本来测试它。但如果我想测试另一个属性呢?如果我想在特定情况下检查TextField是否启用?TextField有一个enabled属性,我可以很容易地使用Widget测试进行检查,但如何使用Flutter driver(或其他框架)执行设备上的测试以检查此属性呢? - Lucie
2个回答

7
如果有人感兴趣:
我想测试的内容不仅是小部件的存在,而且包括它们的状态、属性等。为此,单元测试工具不再足够。
在我的项目中,我使用了 flutter_test 编写小部件测试,并检查所需的属性。
要在真实设备(Android 或 iOS)上测试它,我使用了 integration_test 包(之前是 e2e 包),其可将 flutter_test 的结果转换为与 flutter drive 兼容的格式,可以在此处找到。
使用 integration_test,只需将以下行添加到小部件测试的 main 函数中:
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(在集成测试中启动实际设备)和真实的flutter_driver测试:

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

2
谢谢你的信息!我刚开始学习Flutter的集成测试,并且了解到现在推荐使用integration_test包。但是我不确定integration_testflutter_driver之间有什么区别。你的经验帮助我了解了这一点。 - Inclu Cat

0
我认为Flutter Widget和Flutter Driver之间存在差异。Flutter Widget用于小部件测试,而Flutter Driver用于集成测试。从实际角度来看,我不太确定这意味着什么,但我认为集成测试更容易运行应用程序交互的测试,因为集成测试在实际设备上运行,而不是在小部件测试中。如果我找到更多信息,我会进行更新。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接