How to pass an environment variable to a flutter driver test

前端 未结 3 2281
情书的邮戳
情书的邮戳 2021-02-19 03:50

I want to pass an environment variable to a flutter drive test.

Being able to read the value in the launched application or the test code would both be fi

相关标签:
3条回答
  • 2021-02-19 04:00

    The .env package serves me well:

    include:

    import 'package:dotenv/dotenv.dart' show load, env;
    

    load:

    load();
    

    use:

    test('can log in', () async {
          await driver.tap(emailFieldFinder);
          await driver.enterText(env['USERNAME']);
          await driver.tap(passwordFieldFinder);
          await driver.enterText(env['PASSWORD']);
          await driver.tap(loginButtonFinder);
    
          await Future<Null>.delayed(Duration(seconds: 2));
    
          expect(await driver.getText(mainMessageFinder), "Welcome");
    });
    
    0 讨论(0)
  • 2021-02-19 04:09

    I tried using Dart's Platform.environment to read in env variables before running driver tests and it seems to work fine. Below is a simple example that sets the output directory for the test summaries using the FLUTTER_DRIVER_RESULTS env variable.

    import 'dart:async';
    import 'dart:io' show Platform;
    
    import 'package:flutter_driver/flutter_driver.dart';
    import 'package:test/test.dart';
    
    void main() {
      // Load environmental variables
      String resultsDirectory =
        Platform.environment['FLUTTER_DRIVER_RESULTS'] ?? '/tmp';
      print('Results directory is $resultsDirectory');
    
      group('increment button test', () {
        FlutterDriver driver;
    
        setUpAll(() async {
          // Connect to the app
          driver = await FlutterDriver.connect();
        });
    
        tearDownAll(() async {
          if (driver != null) {
            // Disconnect from the app
            driver.close();
          }
        });
    
        test('measure', () async {
          // Record the performance timeline of things that happen
          Timeline timeline = await driver.traceAction(() async {
            // Find the scrollable user list
            SerializableFinder incrementButton = find.byValueKey(
                'increment_button');
    
            // Click the button 10 times
            for (int i = 0; i < 10; i++) {
              await driver.tap(incrementButton);
    
              // Emulate time for a user's finger between taps
              await new Future<Null>.delayed(new Duration(milliseconds: 250));
            }
    
          });
            TimelineSummary summary = new TimelineSummary.summarize(timeline);
            summary.writeSummaryToFile('increment_perf',
                destinationDirectory: resultsDirectory, pretty: true);
            summary.writeTimelineToFile('increment_perf',
                destinationDirectory: resultsDirectory, pretty: true);
        });
      });
    }
    
    0 讨论(0)
  • 2021-02-19 04:11

    I encountered the same need to pass an environment variable for test application on a device in a Flutter driver test. The challenge was that test applications cannot read environment variables directly from flutter drive command.

    Here is how I solved the problem. The test name for is "field_value_behaviors.dart". Environment variable name is FIRESTORE_IMPLEMENTATION.

    Flutter Drive Command

    Specify environment variable when running flutter drive command:

    $ FIRESTORE_IMPLEMENTATION=cloud_firestore flutter drive --target=test_driver/field_value_behaviors.dart
    

    Driver Program

    Driver program ("field_value_behaviors_test.dart") runs as part of flutter drive program. It can read environment variables:

      String firestoreImplementation =
          Platform.environment['FIRESTORE_IMPLEMENTATION'];
    

    Further, the driver program sends the value to test application running on a device through driver.requestData.

      final FlutterDriver driver = await FlutterDriver.connect();
      // Sends the choice to test application running on a device
      await driver.requestData(firestoreImplementation);
      await driver.requestData('waiting_test_completion',
          timeout: const Duration(minutes: 1));
      ...
    

    Test Application

    Test application ("field_value_behaviors.dart") has group() and test() function calls and runs on a device (simulator). Therefore it cannot read the environment variable directly from flutter drive command. Luckily, the test application can receive String messages from the driver program through enableFlutterDriverExtension():

    void main() async {
      final Completer<String> firestoreImplementationQuery = Completer<String>();
      final Completer<String> completer = Completer<String>();
    
      enableFlutterDriverExtension(handler: (message) {
        if (validImplementationNames.contains(message)) {
          // When value is 'cloud_firestore' or 'cloud_firestore_mocks'
          firestoreImplementationQuery.complete(message);
          return Future.value(null);
        } else if (message == 'waiting_test_completion') {
          // Have Driver program wait for this future completion at tearDownAll.
          return completer.future;
        } else {
          fail('Unexpected message from Driver: $message');
        }
      });
      tearDownAll(() {
        completer.complete(null);
      });
    

    The test application changes the behavior based on the resolved value of firestoreImplementationQuery.future:

      firestoreFutures = {
        // cloud_firestore_mocks
        'cloud_firestore_mocks': firestoreImplementationQuery.future.then((value) =>
            value == cloudFirestoreMocksImplementationName
                ? MockFirestoreInstance()
                : null),
    

    Conclusion: read environment variable by Platform.environment in your driver program. Pass it to your test application by driver.requestData argument.

    The implementation is in this PR: https://github.com/atn832/cloud_firestore_mocks/pull/54

    0 讨论(0)
提交回复
热议问题