【问题标题】:How to pass an environment variable to a flutter driver test如何将环境变量传递给颤振驱动程序测试
【发布时间】:2018-03-10 13:40:03
【问题描述】:

我想将环境变量传递给flutter drive 测试。

能够读取启动的应用程序或测试代码中的值都很好,因为我在应用程序中需要它,如果我只能在测试代码中获取它,我可以使用 @ 将它传递给应用程序987654323@

例如,Travis 允许我指定不以任何方式公开的环境变量(如脚本内容和日志输出)。

我想以这种方式指定用户名和密码,以便在应用程序中使用。

Setting environment variables in Flutter 是一个类似的问题,但这对于我的用例来说似乎过于复杂。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    在 Flutter 驱动程序测试中,我遇到了为设备上的测试应用程序传递环境变量的相同需求。挑战在于测试应用程序无法直接从flutter drive 命令读取环境变量。

    这是我解决问题的方法。测试名称是“field_value_behaviors.dart”。环境变量名称为FIRESTORE_IMPLEMENTATION

    颤振驱动命令

    运行flutter drive命令时指定环境变量:

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

    驱动程序

    驱动程序(“field_value_behaviors_test.dart”)作为flutter drive 程序的一部分运行。它可以读取环境变量:

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

    此外,驱动程序通过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));
      ...
    

    测试应用程序

    测试应用程序(“field_value_behaviors.dart”)具有group()test() 函数调用并在设备(模拟器)上运行。因此它不能直接从flutter drive 命令读取环境变量。幸运的是,测试应用可以通过enableFlutterDriverExtension()接收来自驱动程序的String消息:

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

    测试应用根据firestoreImplementationQuery.future的解析值改变行为:

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

    结论:在你的驱动程序中通过Platform.environment读取环境变量。通过driver.requestData 参数将其传递给您的测试应用程序。

    实现在这个 PR 中: https://github.com/atn832/cloud_firestore_mocks/pull/54

    【讨论】:

      【解决方案2】:

      .env package 非常适合我:

      包括:

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

      加载:

      load();
      

      使用:

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

      【讨论】:

        【解决方案3】:

        我尝试在运行驱动程序测试之前使用 Dart 的 Platform.environment 读取环境变量,它似乎工作正常。下面是一个简单的示例,它使用 FLUTTER_DRIVER_RESULTS 环境变量设置测试摘要的输出目录。

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

        【讨论】:

        • 我在“应用程序代码”而不是在测试文件中运行测试(在我发布此问题后移至此策略)。我想通过将 gequest 发送到已注册的插件来将值传递给设备/模拟器上运行的代码可能会起作用。我会再次cgeck让你知道。
        猜你喜欢
        • 1970-01-01
        • 2018-02-04
        • 2017-05-02
        • 2016-07-31
        • 1970-01-01
        • 2013-12-29
        • 2021-01-15
        • 2016-07-08
        • 1970-01-01
        相关资源
        最近更新 更多