Bird
Raised Fist0
Fluttermobile~20 mins

Widget testing in Flutter - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Widget Testing Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ ui_behavior
intermediate
2:00remaining
What is the output of this widget test?
Given this Flutter widget test code, what text does the test find on the screen?
Flutter
testWidgets('Finds Hello Text', (WidgetTester tester) async {
  await tester.pumpWidget(MaterialApp(home: Scaffold(body: Text('Hello'))));
  expect(find.text('Hello'), findsOneWidget);
});
AThe test finds exactly one widget with text 'Hello'.
BThe test finds no widgets with text 'Hello'.
CThe test finds multiple widgets with text 'Hello'.
DThe test throws a runtime error.
Attempts:
2 left
💡 Hint
Look at the widget tree and the text used in the Text widget.
❓ lifecycle
intermediate
2:00remaining
What happens when tester.pump() is called multiple times?
In Flutter widget tests, what is the effect of calling tester.pump() multiple times in a test?
Flutter
testWidgets('Pump multiple times', (WidgetTester tester) async {
  await tester.pumpWidget(MaterialApp(home: Scaffold(body: Text('Step 1'))));
  await tester.pump();
  await tester.pumpWidget(MaterialApp(home: Scaffold(body: Text('Step 2'))));
  await tester.pump();
  expect(find.text('Step 2'), findsOneWidget);
});
ACalling pump multiple times causes a syntax error.
BOnly the first pump call rebuilds the widget tree; others do nothing.
CEach pump rebuilds the widget tree and processes animations or state changes.
DPump calls clear the widget tree and remove all widgets.
Attempts:
2 left
💡 Hint
Think about what pump does in widget testing.
🔧 Debug
advanced
2:00remaining
Why does this widget test fail with a Finder error?
This test fails with an error that no widget was found. What is the cause?
Flutter
testWidgets('Finds RaisedButton', (WidgetTester tester) async {
  await tester.pumpWidget(MaterialApp(home: Scaffold(body: ElevatedButton(onPressed: () {}, child: Text('Press')))));
  expect(find.byType(RaisedButton), findsOneWidget);
});
AThe ElevatedButton widget does not have a child Text widget.
BThe test is missing a call to tester.pump(), so the widget tree is empty.
CThe MaterialApp widget is missing a theme, causing the button not to render.
DRaisedButton is deprecated and replaced by ElevatedButton, so find.byType(RaisedButton) finds nothing.
Attempts:
2 left
💡 Hint
Check the widget types used in the test and the finder.
❓ navigation
advanced
2:00remaining
What is the navigation stack after this widget test code runs?
Given this widget test code that pushes a new route, what is the current route's text after the test runs?
Flutter
testWidgets('Navigation test', (WidgetTester tester) async {
  await tester.pumpWidget(MaterialApp(home: Scaffold(body: Builder(builder: (context) {
    return ElevatedButton(onPressed: () {
      Navigator.push(context, MaterialPageRoute(builder: (_) => Scaffold(body: Text('Second'))));
    }, child: Text('Go'));
  }))));
  await tester.tap(find.text('Go'));
  await tester.pumpAndSettle();
  expect(find.text('Second'), findsOneWidget);
});
AThe current route still shows the text 'Go'.
BThe current route shows the text 'Second'.
CThe test throws a navigation error because context is invalid.
DThe test fails because pumpAndSettle is missing.
Attempts:
2 left
💡 Hint
Consider what Navigator.push and pumpAndSettle do in tests.
🧠 Conceptual
expert
3:00remaining
Which option correctly tests a widget's state change after a button tap?
You have a StatefulWidget that toggles text between 'Off' and 'On' when a button is tapped. Which test code correctly verifies this behavior?
Flutter
class ToggleWidget extends StatefulWidget {
  @override
  State<ToggleWidget> createState() => _ToggleWidgetState();
}
class _ToggleWidgetState extends State<ToggleWidget> {
  bool isOn = false;
  @override
  Widget build(BuildContext context) {
    return Column(children: [
      Text(isOn ? 'On' : 'Off'),
      ElevatedButton(onPressed: () => setState(() => isOn = !isOn), child: Text('Toggle'))
    ]);
  }
}
A
await tester.pumpWidget(MaterialApp(home: ToggleWidget()));
expect(find.text('Off'), findsOneWidget);
await tester.tap(find.text('Toggle'));
await tester.pump();
expect(find.text('On'), findsOneWidget);
B
await tester.pumpWidget(MaterialApp(home: ToggleWidget()));
await tester.tap(find.text('Toggle'));
await tester.pumpAndSettle();
expect(find.text('Off'), findsOneWidget);
C
await tester.pumpWidget(MaterialApp(home: ToggleWidget()));
expect(find.text('On'), findsOneWidget);
await tester.tap(find.text('Toggle'));
await tester.pump();
expect(find.text('Off'), findsOneWidget);
D
await tester.pumpWidget(MaterialApp(home: ToggleWidget()));
await tester.tap(find.text('Toggle'));
expect(find.text('On'), findsOneWidget);
Attempts:
2 left
💡 Hint
Remember to call pump() after state changes to rebuild the widget tree.

Practice

(1/5)
1. What is the main purpose of testWidgets in Flutter widget testing?
easy
A. To build and test a widget's UI and behavior in isolation
B. To run integration tests across multiple screens
C. To deploy the app to a device
D. To write unit tests for backend logic

Solution

  1. Step 1: Understand testWidgets role

    testWidgets is designed to test widgets individually, focusing on UI and interaction.
  2. Step 2: Differentiate from other test types

    Integration tests cover multiple screens, deployment is unrelated, and unit tests target logic, not UI.
  3. Final Answer:

    To build and test a widget's UI and behavior in isolation -> Option A
  4. Quick Check:

    Widget testing = isolated UI test [OK]
Hint: Remember: testWidgets tests one widget at a time [OK]
Common Mistakes:
  • Confusing widget tests with integration tests
  • Thinking testWidgets deploys the app
  • Mixing unit tests with widget tests
2. Which of the following is the correct way to pump a widget inside a testWidgets function?
easy
A. tester.pumpWidget(MyWidget());
B. await tester.pumpWidget(MyWidget());
C. await tester.runWidget(MyWidget());
D. tester.buildWidget(MyWidget());

Solution

  1. Step 1: Recall the async nature of pumpWidget

    pumpWidget is asynchronous and requires await to complete building the widget.
  2. Step 2: Identify correct method name and usage

    Only pumpWidget is valid; runWidget and buildWidget do not exist.
  3. Final Answer:

    await tester.pumpWidget(MyWidget()); -> Option B
  4. Quick Check:

    Use await with pumpWidget [OK]
Hint: Always await pumpWidget to build widgets in tests [OK]
Common Mistakes:
  • Forgetting to use await with pumpWidget
  • Using non-existent methods like runWidget
  • Calling pumpWidget without await
3. Given this test code snippet, what will the test find?
testWidgets('Finds a Text widget', (WidgetTester tester) async {
  await tester.pumpWidget(const MaterialApp(
    home: Scaffold(
      body: Text('Hello Flutter'),
    ),
  ));

  final textFinder = find.text('Hello Flutter');
  expect(textFinder, findsOneWidget);
});
medium
A. The test will throw a runtime error due to missing MaterialApp
B. The test will fail because the Text widget is not found
C. The test will fail because the text is misspelled
D. The test will pass because the Text widget with 'Hello Flutter' exists

Solution

  1. Step 1: Analyze the widget tree built

    The code builds a MaterialApp with a Scaffold containing a Text widget with 'Hello Flutter'.
  2. Step 2: Check the finder and expectation

    The finder looks for text 'Hello Flutter' which exists exactly once, so expect findsOneWidget will pass.
  3. Final Answer:

    The test will pass because the Text widget with 'Hello Flutter' exists -> Option D
  4. Quick Check:

    Text widget found = test passes [OK]
Hint: Check widget tree and finder text carefully [OK]
Common Mistakes:
  • Assuming test fails without MaterialApp (it is provided)
  • Misreading the text string in finder
  • Expecting multiple widgets but only one exists
4. Identify the error in this widget test code:
testWidgets('Tap button increments counter', (WidgetTester tester) async {
  await tester.pumpWidget(MyCounterWidget());

  await tester.tap(find.byType(ElevatedButton));
  expect(find.text('1'), findsOneWidget);
});
medium
A. Missing await after tap before expect
B. Using wrong finder for button
C. Not pumping widget before tap
D. Expecting wrong text value

Solution

  1. Step 1: Check test flow after tap

    After tapping, the UI needs to update, so tester.pump() or tester.pumpAndSettle() must be awaited.
  2. Step 2: Identify missing pump after tap

    The code misses await tester.pump() after tap, so the UI does not update before the expect check.
  3. Final Answer:

    Missing await after tap before expect -> Option A
  4. Quick Check:

    Always pump after tap to update UI [OK]
Hint: Pump UI after tap before checking results [OK]
Common Mistakes:
  • Forgetting to pump after user interaction
  • Using incorrect finder types
  • Not awaiting async calls
5. You want to test a widget that shows a loading spinner while fetching data, then displays the data text. Which sequence correctly tests this behavior?
hard
A. Pump widget, verify spinner hidden, pumpAndSettle, verify data text visible
B. Pump widget, verify data text visible immediately, pumpAndSettle, verify spinner hidden
C. Pump widget, verify spinner visible, pumpAndSettle, verify data text visible
D. Pump widget, verify spinner visible, pumpWidget again, verify data text visible

Solution

  1. Step 1: Understand loading and data display sequence

    The widget first shows a spinner while loading, then after data loads, shows the data text.
  2. Step 2: Test sequence to verify UI changes

    First pump the widget and check spinner is visible. Then call pumpAndSettle to wait for animations and updates, then verify data text is visible.
  3. Final Answer:

    Pump widget, verify spinner visible, pumpAndSettle, verify data text visible -> Option C
  4. Quick Check:

    Spinner first, then data after settle [OK]
Hint: Check loading UI before and after pumpAndSettle [OK]
Common Mistakes:
  • Checking data text before loading finishes
  • Not using pumpAndSettle to wait for UI updates
  • Assuming spinner hides without pumping
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard