Testing CustomPaint Widgets in Flutter using Golden Image Files

Philip Okonkwo
Flutter Community
Published in
4 min readJun 24, 2018

So you have this beautiful app idea in your head and you decided to build it in everyone’s new favorite cross-platform mobile app development tool: Flutter. You also realize that some of the widgets within flutter will not serve the purpose you want so you decide to design your own custom widgets using the CustomPaint class in Flutter. Then the next important question comes up: how do you test it?

In this post, I will be looking at using what is called Golden Image Files to test CustomPaint widgets. The code for the Thermometer widget I created and the accompanying tests can be found here:

What is A Golden Image File?

A golden image file is an image file that represents the widget as we expect it to be. It is the image against which future tests are run in order to ensure that the visual representation of the widget is exactly as we want it to be. In essence, we perform a pixel by pixel comparison of a screenshot of the widget as we have it currently against the golden image on file that we know is exactly correct.

So how exactly do we create golden images? Lets look at the test/thermometer_widget_test.dart file:

First we import the necessary libraries. Then from line 9, 15, 26 & 38, we create functions that will help us create the ThermometerWidget with several different parameters to test later. Then we create one test along with 4 golden image file tests on lines 64, 75, 86 & 98.

Now let’s look at just one of the tests as an example. Specifically we will be looking at the test for when the temperature is 100°C. We create the widget:

Widget createThermometerWidgetWithColorsAnd100Degrees() {
return Center(
child: RepaintBoundary(
child: ThermometerWidget(
borderColor: Colors.red,
innerColor: Colors.green,
indicatorColor: Colors.red,
temperature: 100.0,
)),
);
}

We wrapped the widget itself in a RepaintBoundary widget which itself is wrapped in a Center widget. This is necessary because golden image files are 2400x200 pixels by default. RepaintBoundary and Center helps to control the size of the image and in this case, we are limiting it to the size of the ThermometerWidget. If you prefer other sizes, you can put a SizedBox in between the Center and RepaintBoundary and make the dimensions of the SizedBox the dimensions of the image you want.

Now we look at the test:

'ThermometerWidget with color and 100 degrees Celsius matches golden file',
(WidgetTester tester) async {
Widget widget = createThermometerWidgetWithColorsAnd100Degrees();
await tester.pumpWidget(widget);
await expectLater(
find.byType(ThermometerWidget),
matchesGoldenFile('golden/thermometerWithColorsAnd100DegGoldenImage.png'),
skip: !Platform.isWindows,
);
});

First we create the widget. Then we pump the widget so it can be tested. Then we check that the image matches an image in the golden file directory. The skip parameter is used to skip the test if the platform the test is being run on is not Windows. The reason for skipping the test when on a different platform is because images created by different platforms are different. So the test will fail if the golden image was created on Windows and the test is run on Linux and vice versa. If you are on a Linux machine, use skip: !Platform.isLinux instead.

Now we can create the golden images. In the terminal, run the following:

flutter test --update-goldens test/thermometer_widget_test.dart

Once it finishes running, you should get a directory called golden inside of the test directory and the golden directory should have 4 golden images created. The thermometerWithColorsAnd100DegGoldenImage.png image should be one of them.

Golden image for thermometer widget at 100°C

And for golden test when 0°C should look like this:

Golden image for thermometer widget at 0°C

You must have noticed that there are no texts in the golden images. The texts have been replaced with colored square rectangles that are the size of the bounding box of the texts and the rectangles have the text’s color. The reason is because testing in Flutter uses Ahem fonts to test the visual representation of texts. There is a proposal to use real text fonts in the future and once that is added, the golden image tool should become even more powerful.

So now that you have your golden images, after any amount of refactoring you can run your normal flutter tests to check that the widget still matches the golden images generated using:

flutter test test/thermometer_widget_test.dart

Should you decide to change the look of your widget for any reason then run the test using “ — update-goldens” again to update the golden image files.

So there you have it. That is how to test CustomPaint widgets in Flutter using golden images.

Happy Fluttering.

--

--