TestVagrant

Flutter Blog Series – Blog 7

Flutter Integration Testing Made Easy: Insider Tips and Tricks

Article

Flutter Integration Testing Made Easy: Insider Tips and Tricks

In our previous blogs of this series, we were :

Case 1 : Test Case Stucked on One Screen

Let us consider a case: in your test, you tapped on a button that navigates you to another screen. But after that, it does not perform any further actions. Your test stuck to the test screen and you have to kill that process manually. One reason that I come across was using pumpAndSettle() after tapping on the Ongoing Animation Screen.

				
					await _tester.tap(find.byKey("key"));
await _tester.pumpAndSettle();
				
			

We have two methods in the flutter integration test package related to waiting for frames to complete i.e pump() and pumpAndSettle().

Pump() :

				
					await _tester.pump(Duration(milliseconds: 100)): 
				
			

It means we are asking the test to wait for 100 msec. It implies that we must know how many frames we want to pump. otherwise, we might face semi-rendering of widgets and the test might fail. After a timeout, it will not wait for further rendering of the widget.

PumpAndSettle() :

				
					await _tester.pumpAndSettle():
				
			

It runs pump() every 100 msec until all the frames are rendered. By default timeout, duration is 10 minutes.

But now consider a case where we have ongoing animation on our screen. And we are waiting for all frames to complete rendering using pumpAndSettle(). It means we are waiting infinite time on screen for the animation to complete. This causes the test to stuck on a single screen.

Avoid using pumpAndSettle() on ongoing Animations.

Case 2: Clicking on a SubText present in RichText

Let’s consider a case: in our app, we have one Richtext which contains clickable Text. Whole RichText is not clickable. In such a situation, the below code will not solve the purpose.

				
					await _tester.tap(find.textContaining(text)); // This will not work when Complete RichText is not clicable
				
			

To solve this problem, we have to Scan RichText’s every TextSpan till the time we found desired Text, and then we have to click on That TextSpan. We can achieve it via –

				
					  /**
     _findTextAndTap this method will search for desired text and once it will get the text and tap on that,
     it will return false to main method, indicating that we have clicked the desired subtext.
     We have to stop visiter search after desired text
  */

   bool _findTextAndTap(InlineSpan visitor, String textToBeMatched) {
    if (visitor is TextSpan && visitor.text == textToBeMatched) {
      (visitor.recognizer as TapGestureRecognizer).onTap();
      return false;
    }
    return true;
  }
  
  Future tapOnSubText(String subText) async {
    final richText = (await _tester.widget(find.byKey("keyOfRichText"))) as RichText;
    richText.text.visitChildren((visitor) => _findTextAndTap(visitor, subText));
  }
				
			

Case 3: Can see the Widget in Tree but Test doesn’t able to Find

We come across a situation where we can see the widget in WidgetTree but when we try to find that widget using testWidget() is not able to reach it. One reason could be, a developer created that widget private intentionally, or unintentionally. so that no other module can access it. There could be other reasons also. In such cases, check widget is present or not. we can use widgetPredicates to find the widget.

Another use case of widgetPrediacte is if you want to fetch a finder with multiple checks. E.g. the Widget should be RickText type and should be desired text. All these can be accomplished.

				
					final Finder widgetFinder = find.byWidgetPredicate((Widget widget) => widget is RichText && widget.text.toPlainText() == text);
return _tester.any(widgetFinder);
				
			

Case 4: Tests are not getting Executed on Firebase Test Lab, Always says No Tests

It took me a long time to discover the root cause. Once we upload the Test and Debug APK to the Firebase Test lab , it expects Test Runner should be present internally to test the apk. We generally use debug apk for testing purposes and we keep minifyEnabled false in general.

If You are also facing the same issue, check your android/app/build.gradle and verify that minifyEnabled is false for debug mode.

				
					buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            useProguard true 
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            signingConfig signingConfigs.debug
            minifyEnabled false
            useProguard true 
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
				
			

Verify minifyEnabled tag is False in your gradle file for debug build type.

Other Related Articles

Share This Article

Scroll to Top