Improving Flutter Test Robustness: Wait Strategies in Integration Testing

Akanksha
3 min readJan 3, 2024

“Strategies for waiting involve temporarily halting test execution until certain conditions are met. They play a crucial role in coordinating test actions with the current state of the application, ensuring that tests proceed only when the application is in an appropriate state.

Various automation testing tools offer strategies such as implicit waits, explicit waits, and global timeouts to achieve this synchronization. Similarly, in Flutter’s integration testing, there exists a range of distinct waiting mechanisms. Understanding the specific uses of these waits enhances the resilience of tests, reducing unpredictability for smoother test runs.

In this blog, aimed at newcomers to Flutter integration testing, I’ll aim to elucidate each wait method by drawing comparisons to commonly used automation tools’ waiting mechanisms, making it easier to comprehend.”

pump() :

The pump method in Flutter integration testing and the sleep method in WebDriverIO (Selenium) serves somewhat similar purposes but operates differently.

sleep in WebDriverIO is a method that pauses the test execution for a specified duration, causing an actual delay. This method is typically used to introduce deliberate delays, especially when synchronization with page loads or other asynchronous operations is required.

pump method simulates the passage of time in the Flutter framework, allowing you to advance the state of your widgets in tests. It’s often used to trigger updates and ensure that the UI reflects the changes made .

 await tester.pump(); // This advances the application's state by a default duration

await tester.pump(Duration(milliseconds: 500)); // Advance the app's state by 500 milliseconds

pumpAndSettle() :

The pumpAndSettle method in Flutter integration testing and the explici waits in WebDriverIO (Selenium) serve somewhat similar purposes.

explict waitin WebDriverIO allows you to wait for certain conditions to be met before executing the next steps in the test script. For instance, you might wait for an element to be visible, clickable, or have specific attributes.

pumpAndSettle It waits until the app reaches a point where no further asynchronous work is pending before proceeding with additional testing.

In case of on going animations, pumpAndSettle may be reached to max timeout, as frame will never be settle down in max time. Make sure to avoid using pumpAndSettle in case of ongoing animations after performing certain actions.

await tester.pumpAndSettle(); // Default Time is 10 Mintues

await tester.pumpAndSettle(Duration(seconds: 3)); // Waits for 3 seconds for the app's UI to settle

pumpFrames() :

pumpFrames is like a remote control for time in our Flutter app. When we use pumpFrames, we're saying, "Hey, let's move time forward by a certain amount," and the app responds by updating things that change over time, like animations or scheduled updates. It helps us fast-forward time in our app so we can see how things change or update over time.

We use this method generally with the below test cases -

Animations
  1. we want to check how an animation looks after a certain time, pumpFrames helps us jump ahead and see it.
  2. Sometimes, things in our app change based on time passing. pumpFrames helps us check these changes at different time points.
  3. Some parts of our app update after a delay. With pumpFrames, we can make sure these updates happen when they're supposed to.
await tester.pumpFrames(Duration(seconds: 3)); // This moves time forward in the app by 3 seconds

TestWidget TimeOut :

In the same vein as the test timeout feature found in frameworks like Jest or Jasmine, Flutter integration testing incorporates a similar mechanism known as testWidget timeout.

This timeout parameter, specified within the testWidget method, functions similarly: if a test exceeds this specified duration, it triggers a test failure.

 testWidgets(
'Sanity Test',
(WidgetTester tester) async {
}
},
timeout: const Timeout(Duration(minutes: 5)),
);

// Maximum Time for This Test is 5 Mintues

By mastering Flutter’s waiting strategies like pump(), pumpAndSettle(), pumpFrames(), and the testWidget timeout, you'll gain precise control over test execution, ensuring tests proceed harmoniously with your app's behavior. Embrace these techniques to enhance test stability and efficiency, steering clear of potential pitfalls and maximizing your testing success.

Explore my series on Flutter integration testing at this link: https://medium.com/@akanksha98/list/flutter-integration-testing-557116e68a11

--

--

Akanksha

I am Akanksha Gupta. By Profession I am Software Engineer with 6 years of experience in IT Industry. Writing and Sharing is my hobby. Living my life fully :)