3

I am testing a flutter application. I am to run an integration testing, just like Espresso and Selenium allow UI testing, based on my reading, I got to understand that testing Flutter UI will require setting up the integration model. In Selenium findById and Espresso, we can use , R.id.unique_element_id.

I have tried undertsanding the unique id to reference widgets in Flutter but do not understand. Any simple test for a form like this

mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new TextFormField(
              decoration: new InputDecoration(
                  labelText: 'Enter your username'
              ),
            ),
            new TextFormField(
              decoration: new InputDecoration(
                  labelText: 'Enter your phone number'
              ),
              keyboardType: TextInputType.number,
            ),

            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],

Setup the test file like this

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

    void main() {
      FlutterDriver driver;

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

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


test('tap on the button, verify result', () async {
    final SerializableFinder username = find.byValueKey('usernametextfield');
    expect(username, isNotNull);
    //insert value into username

    final SerializableFinder phonenumber = find.byValueKey('phone');
    expect(phonenumber, isNotNull);
    //insert value into phonenumber
});

How do I create such a tetscase and run. the comments //insert value into username and //insert value into phonenumber are actual testcases I want to complete.

1

3 Answers 3

4

flutter_driver is dead now(Discontinued) you can use this integration_test I create login flow example

  1. First add a dependency in pubspec.yaml under dev

           dev_dependencies:
             flutter_test:
               sdk: flutter
             test: ^1.9.4
             integration_test: ^1.0.1
    
  2. Your package should have a structure that looks like this: enter image description here

  3. Add this in test/test_driver/integration_test.dart

                   import'package:integration_test/integration_test_driver.dart';
    
                                   Future<void> main() => integrationDriver(); 
    

4.Add this in integration_test/foo_test.dart example

                                    void main() {
                                      IntegrationTestWidgetsFlutterBinding.ensureInitialized();
  
                                      testWidgets("Sign in test example", (WidgetTester tester) async {
                                        final Finder signInEmailField = find.byKey(Key('signInEmailField'));
                                        final Finder signInPasswordField = find.byKey(Key('signInPasswordField'));
                                        final Finder signInSaveButton = find.byKey(Key('signInSaveButton'));
  
                                        await tester.pumpWidget(MyApp());
  
                                        await tester.pumpAndSettle();
  
                                        await tester.tap(find.byKey(Key('signInEmailField')));
                                        await tester.enterText(signInEmailField, "[email protected]");
  
                                        await tester.tap(signInPasswordField);
                                        await tester.enterText(signInPasswordField, "123456");
  
                                        await tester.tap(signInSaveButton);
                                        print("button tapped");
                                        await tester.pumpAndSettle(Duration(seconds: 1));
                                        expect(
                                            find.byWidgetPredicate((widget) =>
                                                widget is AppBar &&
                                                widget.title is Text &&
                                                (widget.title as Text).data.startsWith("ToDoApp")),
                                            findsOneWidget);
  
                                        await tester.pumpAndSettle(Duration(seconds: 1));
                                      });
                                    }
  1. Add key like we set in flutter_driver

                       appBar: AppBar(
                         title: Text(
                           'ToDoApp',
                           key: Key("toDoKey"),
                         ),
                         backgroundColor: Colors.brown[400],
                       ),
    
  2. Foo last run the command in your terminal flutter drive
    --driver=test_driver/integration_test.dart
    --target=integration_test/foo_test.dart

Thanks.. happy Fluttering

Sign up to request clarification or add additional context in comments.

Comments

1

Not sure if you found an answer to your question, but I am posting a solution here. Hope it helps.

Basically, you need to define key property on the TextFormField widget, which will help you to identify that widget uniquely and then you can perform actions on it. Example:

new TextFormField(
              key: Key('userNameTextField'),
              decoration: new InputDecoration(
                  labelText: 'Enter your username'
              ),
            ),

and then in your test file, you'll write this:

test('tap on the button, verify result', () async {
    final SerializableFinder username = find.byValueKey('userNameTextField');
    expect(username, isNotNull);
    await driver.waitFor(username);
    await driver.enterText('Test');

  // repeat above for `phoneNumber` widget.

    final SerializableFinder phonenumber = find.byValueKey('phone');
    expect(phonenumber, isNotNull);
    //insert value into phonenumber
});

1 Comment

flutter_driver has now been discontinued (see next answer)
1

I have created a method to enter text. Maybe this will be useful for someone.

  Future<void> enterText(SerializableFinder itemFinder, String text) async {
    final isTextFieldPresent = await isPresent(itemFinder);

    if (isTextFieldPresent) {
      await _driver.tap(itemFinder);
      await _driver.enterText(text);
      await _driver.waitFor(find.text(text));
    } else {
      expect(isTextFieldPresent, true, reason: 'Cannot find text field');
    }
  }

And here is isPresent method I use above

  Future<bool> isPresent(SerializableFinder itemFinder,
      {int delayInMilis = 1000}) async {
    final timeout = Duration(milliseconds: delayInMilis);
    try {
      await _driver.waitFor(itemFinder, timeout: timeout);
      return true;
    } catch (exception) {
      return false;
    }
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.