2

I was following this example to test if a CircularProgressIndicator is present in my view, but even though the Flutter build tree shows the widget is present, I keep getting the following exception:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
  Actual: _WidgetFinder:<zero widgets with the given widget
(CircularProgressIndicator(<indeterminate>)) (ignoring offstage widgets)>
   Which: means none were found but one was expected

When the exception was thrown, this was the stack:
#4      main.<anonymous closure> (file:///D:/xxxx/xxxx/xxxx/test/widget_test/widget_test.dart:173:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

This was caught by the test expectation on the following line:
  file:///D:/xxxx/xxxx/xxxx/test/widget_test/widget_test.dart line 173
The test description was:
  ViewRequest: Waiting Types List
════════════════════════════════════════════════════════════════════════════════════════════════════

Edit

I've made a method that builds a MaterialApp with just a CircularProgressIndicator Widget as its "child":

Widget createMockViewRequest() {
  return MaterialApp(
      title: 'SmartDevice Simulator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const CircularProgressIndicator());
}

And the following test still keeps failing with the same exception:

testWidgets('ViewRequest: Waiting Types List', (WidgetTester tester) async {
  const childWidget = CircularProgressIndicator();

  // Build our app and trigger a frame.
  await tester.pumpWidget(createMockViewRequest());

  // Verify that the page is loading until we receive the types.
  expect(find.byWidget(childWidget), findsOneWidget);

  await tester.pumpAndSettle();
});

Am I doing something wrong? Maybe the MaterialApp doesn't count as a container? But in that case I fail to understand why it should not.

2 Answers 2

4

There are a few things to change in order to make it work.

First of all, if you use await tester.pumpAndSettle() while testing a widget with an infinite animation such as a CircularProgressIndicator, the test will fail because it is waiting for the last frame to be updated but the animation never ends, therefore a timeout is thrown.

Apart from that, your test is failing because of the finder that you are using, you are trying to find the very same instance that you are providing to the expect in your UI, and this is not the case, since the instance that gets built in the UI is different from the one that you are creating inside your test, in this case, if you want to check if there is a CircularProgressIndicator on the UI, you should use the find.byType finder, which searches for a Widget of the provided type in the widget that has been built.

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

1 Comment

Thank you so much for the solution and the explaination. Actually the reason why I put a .pumpAndSettle() method is because I've got a timer that replaces the CircularProgressIndicator with another Widget (simulating the collecting of the information needed), but still I didn't know that the animation of CircularProgressIndicator would make the app keep loading frames. The more you know :)
2

You have to change your example like this:

 Widget createMockViewRequest(Widget widget) {
    return MaterialApp(
      title: 'SmartDevice Simulator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: widget,
    );
  }

  testWidgets('ViewRequest: Waiting Types List', (WidgetTester tester) async {
    const childWidget = CircularProgressIndicator();

    // Build our app and trigger a frame.
    await tester.pumpWidget(createMockViewRequest(childWidget));

    // Verify that the page is loading until we receive the types.
    expect(find.byWidget(childWidget), findsOneWidget);
  });

or like this:

 Widget createMockViewRequest() {
    return MaterialApp(
      title: 'SmartDevice Simulator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const CircularProgressIndicator(),
    );
  }

  testWidgets('ViewRequest: Waiting Types List', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(createMockViewRequest());

    // Verify that the page is loading until we receive the types.
    expect(find.byType(CircularProgressIndicator), findsOneWidget);
  });

Please note, that I remove await tester.pumpAndSettle(); because it waits when the animation completes on your page, but CircularProgressIndicator will spin to infinity so that you will have a timeout exception.

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.