简体   繁体   中英

Flutter widget vs Flutter driver

I'm writing tests for a mobile App written in Flutter . I followed this Flutter Cookbook on testing Flutter apps, to learn how to write widget and integration tests.

This tutorial works perfectly, but I'm still stuck with my own Integration tests.

To simplify, let's assume I have an app, containing only a 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()),
      ),
    );
  }
}

I want to write a test for this app. For instance, I want to test the following scenario:

  • Open the app
  • Check that the TextField is empty
  • Select the TextField
  • Enter "hello, world!"
  • Check that TextField contains "hello, world!"

I wrote the following Widget test, which works fine:

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!"));
  });
}

This test passes, but I wanted to write an Integration test, doing more or less the same, to be able to test it on a real device. Indeed if this Widget test passes, it will probably pass on all device. But in my app I have more complex widgets and interactions between them, I want to be able to launch tests on both Android and iOS.

I tried to write integration tests using Flutter driver , but I did not find what I wanted in the documentation and examples.

How can I check Widget properties, to verify that my App behaves as expected?

I wrote the following sample:

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!
    });
  });
}

The Flutter Cookbook tutorial explains how to retrieve an object by its Text, this would help to check if the Text is present, but for instance is it possible to check that a Container color is red? Where is the limit between Widget and Integration tests?

Writing Widget tests is pretty straighforward, but I didn't find many examples or documentation about how to write more complexe integration tests using Flutter driver.

If anyone is interested:

To be able to test what I want (not only the presence of widgets, but also theirs states, their properties,...) test driver was not enough for me.

What I did in my project, is to use the flutter_test to write widget tests and check the properties I want.

To test it on a real device (Android or iOS), I used the integration_test package (previously e2e package) available here , which adapts flutter_test results to a format compatible with flutter drive.

To use integration_test, add this line in the main of your widget tests:

IntegrationTestWidgetsFlutterBinding.ensureInitialized();

Then create a file (eg integration_test.dart ) in your test_driver folder with this content:

import 'package:integration_test/integration_test_driver.dart';

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

Then you can launch these driver test by running:

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

With your widgets tests wrote in the file test/widget_test/widget_test.dart .

It really helped me, since some widgets did not have the same behavior on Android and iOS.

Today I use both flutter_test (launched on real device with integration_test) and real flutter_driver tests:

  • I write widget tests to check a single widget, or a single page,
  • I use flutter driver to write more sophisticated scenarios to test the whole application.

I think there's a difference between flutter widget and flutter driver. In that, flutter widgets is for widget tests and flutter driver is for integration tests. I'm not exactly sure what that means on a practical standpoint but I think integration test are easier to run tests on application interactions that would be made by a user since integration tests run on an actual device as compared to widget tests. Will update if I find more information on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM