Skip to content
tezvyn:
Menu

WidgetTester: Programmatically Drive Your Flutter UI

Source: api.flutter.devMediumHow cards are made

WidgetTester is a robot user for your app, programmatically tapping, dragging, and entering text. Use it in testWidgets to simulate user flows and verify UI state. The footgun is forgetting tester.pump() after an action; you'll assert against a stale UI.

Why it exists

To test a widget's behavior, you need to simulate how a user interacts with it and how it responds over time. Manually testing every tap and scroll is slow and error-prone. WidgetTester provides a programmatic way to automate these interactions in a controlled, repeatable test environment.

The mental model

WidgetTester is a robot user for your app that also controls time. It can find a widget on the screen (like a button with the text 'Save'), perform an action on it (like a tap), and then fast-forward time to see the result (like a 'Success' message appearing). It replaces a human finger with code.

How it works

A test starts by loading your widget tree using tester.pumpWidget(). You then use Finders (e.g., find.text('Submit')) to locate specific widgets. Once found, you can call action methods like tester.tap(), tester.drag(), or tester.enterText(). The key is the tester.pump() method. Every time you call it, you tell Flutter to advance a single frame, rebuilding widgets and processing animations. Calling pump(Duration(seconds: 1)) fast-forwards time, completing any timers or animations within that duration instantly. Finally, you use expect() with matchers like findsOneWidget to verify the UI is in the expected state.

When to use it

Use WidgetTester inside testWidgets blocks for almost all your UI testing needs. It's ideal for verifying that: first, user input triggers the correct state changes; second, widgets render correctly based on their state; and third, complex user flows involving multiple steps work as intended.

When not to use it

WidgetTester is not for pure business logic that has no UI component; use a standard test() for that. It also doesn't run on a real device, so it can't test platform-specific integrations like camera access or push notifications. For that, you would need a full integration test using a tool like patrol.

One canonical example

A common test is verifying a form submission. First, you'd use tester.pumpWidget() to load the form. Then, tester.enterText(find.byType(TextField), 'user input') to fill a field. Next, tester.tap(find.text('Save')). Crucially, you must then call await tester.pump() to let the UI react to the tap, perhaps showing a loading indicator. After the work is done (simulated with another pump), you would expect(find.text('Success'), findsOneWidget) to confirm the flow completed.

Interview question

What is the primary purpose of calling "tester.pump()" after simulating a user interaction in a WidgetTester test?

  • a.To identify the widget that received the interaction.
  • b.To assert that the UI has reached its expected state.
  • c.To trigger a UI rebuild and process any pending frame updates.Correct
  • d.To instantly complete all ongoing timers and animations.
Why?

tester.pump() is essential to advance the UI by one frame, allowing Flutter to rebuild widgets and process any state changes or animations triggered by the simulated user interaction. While tester.pump(Duration) can fast-forward time to complete animations and timers, tester.pump() by itself only advances a single frame, not necessarily completing all ongoing operations instantly.

Just read this? Test yourself on what you have been reading.

Read the original → api.flutter.dev

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on flutter — each one lists the topics its interview covers.

See open roles