Flutter:flutter_driver 错误消息和应用程序屏幕在测试时保持黑色

pat*_*u22 6 flutter flutter-test

我正在尝试为我的 Flutter 应用程序设置一些集成测试,但遇到了一些麻烦。虽然在调试模式下运行我的应用程序工作正常,但当我尝试使用 flutter_driver 运行它时,该应用程序保持黑色。
这是我的flutter_driver/app.dart代码的代码:

import 'package:flutter_driver/driver_extension.dart';
import 'package:[MY_APP_NAME]/main.dart' as app;

void main() {
  // This line enables the extension.
  enableFlutterDriverExtension();

  // Call the `main()` function of the app, or call `runApp` with
  // any widget you are interested in testing.
  app.main();
}  
Run Code Online (Sandbox Code Playgroud)

这是我的flutter_driver/app_test.dart文件的代码:


// Imports the Flutter Driver API.
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';

void main() {
  group('My first test group', () {
    // First, define the Finders and use them to locate widgets from the
    // test suite. Note: the Strings provided to the `byValueKey` method must
    // be the same as the Strings we used for the Keys in step 1.

    final welcomeQuestion = find.byValueKey('welcomeQuestion');
    FlutterDriver driver;
    // Connect to the Flutter driver before running any tests.
    setUpAll(() async {
      driver = await FlutterDriver.connect();
    });

    // Close the connection to the driver after the tests have completed.
    tearDownAll(() async {
      if (driver != null) {
        driver.close();
      }
    });

    test('check flutter driver health', () async {
      Health health = await driver.checkHealth();
      print(health.status);
    });

    test('Check welcomeQuestion', () async {
      // Use the `driver.getText` method to verify the counter starts at 0.
      expect(await driver.getText(welcomeQuestion), "Are you feeling good today?");
    });
  });
}

Run Code Online (Sandbox Code Playgroud)

这是我在运行flutter drive --target=test_driver/app.dart以执行测试时收到的错误消息:

00:00 +1 -1: [APP-NAME] Check welcomeQuestion [E]
  DriverError: Error in Flutter application: Uncaught extension error while executing get_text: 'package:flutter_driver/src/extension/extension.dart': Failed assertion: line 189 pos 14: 'WidgetsBinding.instance.isRootWidgetAttached || !command.require
sRootWidgetAttached': No root widget is attached; have you remembered to call runApp()?
  #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:40:39)
  #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
  #2      FlutterDriverExtension.call (package:flutter_driver/src/extension/extension.dart:189:14)
  <asynchronous suspension>
  #3      BindingBase.registerServiceExtension.<anonymous closure> (package:flutter/src/foundation/binding.dart:512:32)
  <asynchronous suspension>
  #4      _runExtension (dart:developer-patch/developer.dart:84:23)

  Original error: null
  Original stack trace:
  null

  package:flutter_driver/src/driver/driver.dart 433:7   FlutterDriver._sendCommand
  ===== asynchronous gap ===========================
  dart:async/future_impl.dart 22:43                     _Completer.completeError
  dart:async-patch/async_patch.dart 40:18               _AsyncAwaitCompleter.completeError
  package:flutter_driver/src/driver/driver.dart         FlutterDriver._sendCommand
  ===== asynchronous gap ===========================
  dart:async/zone.dart 1053:19                          _CustomZone.registerUnaryCallback
  dart:async-patch/async_patch.dart 77:23               _asyncThenWrapperHelper
  package:flutter_driver/src/driver/driver.dart         FlutterDriver._sendCommand
  package:flutter_driver/src/driver/driver.dart 677:41  FlutterDriver.getText
  ===== asynchronous gap ===========================
  dart:async/zone.dart 1053:19                          _CustomZone.registerUnaryCallback
  dart:async-patch/async_patch.dart 77:23               _asyncThenWrapperHelper
  package:test_api/src/backend/declarer.dart            Declarer.test.<fn>.<fn>.<fn>
  package:test_api/src/backend/invoker.dart 250:15      Invoker.waitForOutstandingCallbacks.<fn>
  ===== asynchronous gap ===========================
  dart:async/zone.dart 1045:19                          _CustomZone.registerCallback
  dart:async/zone.dart 962:22                           _CustomZone.bindCallbackGuarded
  dart:async/timer.dart 52:45                           new Timer
  dart:async/timer.dart 87:9                            Timer.run
  dart:async/future.dart 174:11                         new Future
  package:test_api/src/backend/invoker.dart 399:21      Invoker._onRun.<fn>.<fn>.<fn>

00:00 +1 -1: [APP-NAME] (tearDownAll)
00:00 +1 -1: Some tests failed.

Unhandled exception:
Dummy exception to set exit code.
#0      _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:1112:29)
#1      _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
#2      _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
#3      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:391:30)
#4      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
#5      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
Stopping application instance.
Driver tests failed: 255
Run Code Online (Sandbox Code Playgroud)

值得一提的是,应用程序屏幕保持黑色,因此驱动程序似乎无法附加到原始应用程序并正确运行它。有人知道如何解决这个问题吗?

更新

运行flutter --version

Flutter 1.7.8+hotfix.4 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 20e59316b8 (8 weeks ago) • 2019-07-18 20:04:33 -0700
Engine • revision fee001c93f
Tools • Dart 2.4.0
Run Code Online (Sandbox Code Playgroud)

这是我的 main.dart 的黑化版本:

import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_statusbarcolor/flutter_statusbarcolor.dart';
[... + many additional imports from other private packages]

void main() async {
  //load the json config globally
  await Config().loadConfig();
  await SharedPrefsService().init();
  await RealmService().init();
  SessionHistoryService().init();
  final Router router = Router();

  [... a lot of router.define() functions....]

  //set statusbar color
  FlutterStatusbarcolor.setStatusBarWhiteForeground(true);

  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) {
    runApp(new MaterialApp(
        localizationsDelegates: [
          const AppLocalizationsDelegate(),
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate
        ],
        supportedLocales: [
          const Locale('en', 'US'), // English
          const Locale('de', 'DE'), // German
          // ... other locales the app supports
        ],
        localeResolutionCallback:
            (Locale locale, Iterable<Locale> supportedLocales) {
          for (Locale supportedLocale in supportedLocales) {
            if (supportedLocale.languageCode == locale.languageCode ||
                supportedLocale.countryCode == locale.countryCode) {
              //For Localization Testing:
              // return const Locale('de', 'DE');
              return supportedLocale;
            }
          }

          return supportedLocales.first;
        },
        title: 'MY APP NAME',
        home: SharedPrefsService().isFirstLaunch()
            ? FirstLaunchScreen(true)
            : MainMenuPage(),
        onGenerateRoute: router.generator));
  });
}
Run Code Online (Sandbox Code Playgroud)

Gui*_*lva 6

就我而言,这就足够了:

// connects with the current running application
driver = await FlutterDriver.connect();

// Wait for the first frame to be rasterized during the app launch.
await driver.waitUntilFirstFrameRasterized();
Run Code Online (Sandbox Code Playgroud)

好吧,不知道为什么它被否决了,这是关于那个的 gh 问题:https : //github.com/flutter/flutter/issues/41029

更新:看来我们有一个新的库来取代 FlutterDriver,你不再需要关心这些问题了:https : //medium.com/flutter/updates-on-flutter-testing-f54aa9f74c7e :)


Nem*_*vić 5

我有同样的问题,似乎测试在 main.dart 中 main() 的 .init() 方法完成之前开始执行。尝试在测试开始时设置暂停,看看它是否有效,就我而言。我们正在寻找一种解决方案,如何在不使用硬编码暂停的情况下等待整个 main() 执行完毕然后开始测试执行。希望能帮助到你

test('Check welcomeQuestion', () async {

  await sleep(Duration(seconds: 5));

  // Use the `driver.getText` method to verify the counter starts at 0.
  expect(await driver.getText(welcomeQuestion), "Are you feeling good today?");
});
Run Code Online (Sandbox Code Playgroud)


Dar*_*han 1

假设您的屏幕上只有文本Are you feeling good today?,我重新创建了您的案例,并且在运行颤动驱动程序测试时没有看到任何问题或黑屏。我看到测试执行成功:

在此输入图像描述

main.dart的如下:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Are you feeling good today?', key: Key('welcomeQuestion'),)
      )
Run Code Online (Sandbox Code Playgroud)

app.dart:

void main() {
  // This line enables the extension
  enableFlutterDriverExtension();

  // Call the `main()` function of your app or call `runApp` with any widget you
  // are interested in testing.
  app.main();

}
Run Code Online (Sandbox Code Playgroud)

app_test.dart:

group('My first test group', () {
    // First, define the Finders and use them to locate widgets from the
    // test suite. Note: the Strings provided to the `byValueKey` method must
    // be the same as the Strings we used for the Keys in step 1.

    final welcomeQuestion = find.byValueKey('welcomeQuestion');
    FlutterDriver driver;
    // Connect to the Flutter driver before running any tests.
    setUpAll(() async {
      driver = await FlutterDriver.connect();
    });

    // Close the connection to the driver after the tests have completed.
    tearDownAll(() async {
      if (driver != null) {
        driver.close();
      }
    });

    test('check flutter driver health', () async {
      Health health = await driver.checkHealth();
      print(health.status);
    });

    test('Check welcomeQuestion', () async {
      // Use the `driver.getText` method to verify the counter starts at 0.
      expect(await driver.getText(welcomeQuestion), "Are you feeling good today?");
    });
  });
Run Code Online (Sandbox Code Playgroud)