New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Widget tests timeout if you await a future defined in setUp #5728

Open
drewwarren opened this Issue Sep 2, 2016 · 9 comments

Comments

Projects
None yet
7 participants
@drewwarren

drewwarren commented Sep 2, 2016

import "dart:async";

import "package:flutter_test/flutter_test.dart";

void main() {
  Future future;

  setUp(() {
    future = new Future.value();
  });

  testWidgets("awaiting future with value from setUp works",
      (WidgetTester tester) async {
    await future;
  });
}
flutter_test_async$ flutter test test/async_widget_test.dart 
00:05 +0 -1: - awaiting future with value from setUp works                                         
  TimeoutException after 0:00:05.000000: Test timed out after 5 seconds.
  dart:async                _StreamController.add
  websocket_impl.dart 1111  _WebSocketImpl._WebSocketImpl._fromSocket.<fn>
  dart:async                _EventSinkWrapper.add
  websocket_impl.dart 333   _WebSocketProtocolTransformer._messageFrameEnd
  websocket_impl.dart 228   _WebSocketProtocolTransformer.add

00:05 +0 -1: Some tests failed.        
[✓] Flutter (on Mac OS, channel unknown)
    • Flutter at /Users/drewwarren/flutter
    • Framework revision 852a00a17b (8 days ago), 2016-08-25 14:23:13
    • Engine revision c4022b61fa
    • Tools Dart version 1.19.0-dev.5.0

[x] Android toolchain - develop for Android devices
    x Android Studio / Android SDK not found. Download from https://developer.android.com/sdk/
      (or visit https://flutter.io/setup/#android-setup for detailed instructions).

[✓] iOS toolchain - develop for iOS devices (Xcode 7.3.1)
    • XCode at /Applications/Xcode.app/Contents/Developer
    • Xcode 7.3.1, Build version 7D1014

[✓] Atom - a lightweight development environment for Flutter
    • flutter plugin version 0.2.4
    • dartlang plugin version 0.6.37
@Hixie

This comment has been minimized.

Contributor

Hixie commented Sep 2, 2016

testWidgets is using a FakeAsync, and setUp's future is created outside that FakeAsync scope.
I tried reproducing this using only FakeAsync, but couldn't, so I'm not 100% sure what's going on.
@yjbanov any ideas before I try to minimise the heck out of flutter_test? :-)

@yjbanov

This comment has been minimized.

Contributor

yjbanov commented Sep 3, 2016

This does look zone-related. I couldn't reproduce using just FakeAsync either. However, what I noticed is that in a plain package:test + FakeAsync test the test zone is a direct child of the setUp zone, but it is a grandchild in a package:flutter_test test.

// package:test
setUp zones: 421730508
test zones: 180409779 < 421730508
// package:flutter_test
setUp zones: 585864271
test zones: 799539283 < 436113664 < 585864271

Here's the plain code I used:

import "dart:async";

import "package:quiver/testing/async.dart";
import "package:test/test.dart";

void main() {
  Future future;

  zoneChain() {
    var zone = Zone.current;
    var zones = [];
    while(zone != null) {
      zones.add(zone);
      zone = zone.parent;
    }
    return zones.map((z) => z.hashCode).join(' < ');
  }

  setUp(() {
    print('setUp zones: ${zoneChain()}');
    future = new Future.value();
  });

  test("awaiting future with value from setUp works", () async {
    var fakeAsync = new FakeAsync();
    fakeAsync.run((_) async {
      print('test zones: ${zoneChain()}');
      await future;
    });
    fakeAsync.flushMicrotasks();
  });
}
@Hixie

This comment has been minimized.

Contributor

Hixie commented Sep 3, 2016

@nex3 any ideas?

@Hixie Hixie modified the milestone: Flutter 1.0 Sep 12, 2016

@Hixie Hixie added the framework label Sep 12, 2016

@eseidelGoogle

This comment has been minimized.

Contributor

eseidelGoogle commented Feb 3, 2017

Do we think this is a package:test bug, should we move it there?

@Hixie

This comment has been minimized.

Contributor

Hixie commented Feb 3, 2017

we've no idea.

@zoechi

This comment has been minimized.

Contributor

zoechi commented Aug 27, 2018

Is this still an issue?

@apaatsio

This comment has been minimized.

apaatsio commented Oct 22, 2018

From what I understand you are supposed to use tester.runAsync() when you want to test async code like that with testWidgets.

This works:

testWidgets("awaiting future with value from setUp works",
    (WidgetTester tester) async {
  await tester.runAsync(() async {
    await future;
  });
});

Edit: added await to tester.runAsync().

@yjbanov

This comment has been minimized.

Contributor

yjbanov commented Oct 22, 2018

I believe @mdebbar saw this recently too. Yes, any real asynchronous work has to go through tester.runAsync(). However, we should try to find a way for tests to not hang, but instead fail with a message complaining about real async work done inside the test. Not sure if that's possible 🤔

@mdebbar

This comment has been minimized.

Contributor

mdebbar commented Oct 22, 2018

And don’t forget to await on runAsync:

await tester.runAsync(() async {
  await future;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment