Published in


Flutter Demo by KBTG: Testing Your UI With Golden Test in Flutter

Try to compare pixels at the head of the bird in the middle

A golden test is a type of unit test to ensure that your UI stays the same after adding new functionalities to your widget. It saves the snapshot image of your last UI and compares it with the new one. If the new UI looks different than before, the unit test will fail and show an error.

Since Flutter is based on widgets, we usually end up with a ton of them in our app. My app has about 100 widgets in total, not to mention each one might have different states such as Error State or Progressing State, or even Exceptional State. Hence, we have more combinations for all widgets. Some states in widgets require some effort to test because you have to mock up your data to show that widget. Moreover, what would happen if you have 4–5 developers and everybody starts writing their own widget even though they exist in the project already?

That’s why we have to develop a solution to solve this problem; that’s why this tutorial was born. For this tutorial, I’m using this lib from eBay called golden_toolkit

Now let’s see an example. First, I installed the lib from golden_toolkit

golden_toolkit: ^0.9.0

I use a sample avatar.dart that I quickly create as an example and add to the project. The result will be similar to this.

The avatar has many parameters like hasBorder, hasCloud, hasCloudCenter, and you can customize the color, font size, and so on. Say we use only 4 boolean flags, we will have 16 possibilities in our UI, excluding color, image, and font size. When we need to add something new and change something in the widget, how do we know that all those 16 possibilities will look the same? Do we test every single one of those? I can tell you right now that people rarely do it. Even testers are not aware of it unless we have these in their test case, which is impossible. We can’t mock up all those possibilities everywhere and show them to the testers. They might test it, but usually they focus on the end-to-end testing and functionality, except for when these UI changes impact the business requirements.

We, developers, are lazy and don’t want to test it every time for sure. So why don’t we let the code test it for us? That’s where the golden test comes in. I get this idea from my experience with Swift using Facebook Snapshot testing.

Due to Facebook’s very complex UI, it’s understandable why they invent and integrate this into their test pipeline.

Here’s a reference image that I get from running golden_testing with many combinations of sizing and parameters. You can see that if I increase the size of the widget, the layout will be broken, so I recognize very early on that this widget is not scalable and we need to fix it.

click on the image to enhance

Here’s my repo in GitHub.

Here are two tricks that I would like to mention.

1.How to test app with localization

I create MockDelegate and pass as mockLocalization to override language loading to load from the internal JSON instead of loading from the Internet. Since our test can’t use a network, we have to mock up some data that we need from the network and inject it into the Material app with that widget. Below is an example for testing CloudBox the widget, then we pass _buildApp to the golden test.

MaterialApp _buildApp(CloudItem cloudBoxData) {   return MaterialApp(      localizationsDelegates: [      mockLocalization,      GlobalMaterialLocalizations.delegate,      GlobalWidgetsLocalizations.delegate,      DefaultCupertinoLocalizations.delegate,      GlobalCupertinoLocalizations.delegate   ],   debugShowCheckedModeBanner: false,   home: Scaffold(      body: Container(      color: AppColor.white, child: CloudBox(data: cloudBoxData)),      ),   );}

2.How to test app with animations

Sometimes, you might have an animation in your widget after you do some actions after a period of time, and you want to take a screenshot after that. The sample code below shows that we’re going to take a screenshot 3 seconds later so that the animation can finish first.

await screenMatchesGolden(tester, 'cloud_box', customPump: (widget){   return widget.pump(Duration(seconds: 3));});

Golden testing is a cool idea but try not to overuse it since it takes time to test. Some of the golden tests might take up to 10 seconds or more if you have a more complex UI, while you can do up to 30–40 of unit tests in those 10 seconds. I apply this to our project and share it with testers and designers, even fellow developers to check if we already have this widget yet. Next step, I’m finding a way to add all of the widgets into a storybook-like documentation in React but still can’t find the way to make it automatic yet. If I accomplish this, our developers will have a UI documentation for others to check out before they create the new one.

Want to read more stories like this? Or catch up with the latest trends in the technology world? Be sure to check out our website for more at www.kbtg.tech




ONE KBTG Culture: ONE Step Ahead, ONE Goal, ONE Team, Number ONE

Recommended from Medium

order of arithmetic operations revisited : streamlined knowledge

What’s Wrong With Python Pandas?

A Quantum Leap for the Web

Logging to AWS Elasticsearch Service from Kubernetes

AMA Recap: October 04th, 2019

Fixing Circular References in Access Queries

Right time to choose SVG vs Data URIs vs PNGs in your Web Design

DevOps / SRE — Top Links Last Week

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Amorn Apichattanakul

Amorn Apichattanakul

Senior Flutter/iOS Software Engineer

More from Medium

Flutter Navigation with AutoRoute

Flutter Slidable Package

Using themes in Flutter

Use themes in Flutter

Integrating Flutter iOS App With Firebase