Testing is crucial for delivering high-quality apps. In this article, I’d like to discuss one of the lesser-known features of Widget testing — Golden tests.
What is a Golden test?
Golden tests are Widget tests. A special matcher compares your widget to an image file and expects them to be identical. Golden files are image files generated from a manually verified widget, serving as the reference for comparison.
How to create a Golden test?
For this example, let’s create a golden test for Flutter’s “Hello World” app.
In the Flutter project’s test
folder, we create a file called golden_widget_test.dart
.
And add the following code:
void main() { testWidgets('Golden test', (WidgetTester tester) async { await tester.pumpWidget(MyApp()); await expectLater( find.byType(MyApp), matchesGoldenFile('main.png'), ); }); }
Let me explain what happens above…
You start creating your Golden test as a usual Widget test by pumping your widget.
await tester.pumpWidget(MyApp());
Once the widget is pumped, it is compared with the image:
await expectLater(find.byType(MyApp), matchesGoldenFile('main.png'));
We use expectLater because matchesGoldenFile is an asynchronous matcher. The method expectLater works exactly as the method expect, but returns Future that completes when the matcher has finished matching.
How to generate Golden files?
Now it is time to generate these manually verified images. If you’d like to generate images for all your Golden tests (or update old ones), run:
flutter test --update-goldens
The main.png file should appear in your project’s test folder. Don’t forget to add it to version control.
For only one particular test you can run:
flutter test --update-goldens <path_to_test_file>
How to run tests?
You can now run tests as normal unit tests to verify that the generated Golden files match your widget.
flutter test
Complete Sample
The whole “Hello world” sample is here or you can have a look at what was changed since “flutter create” command. Feel free to clone the project and play around. For example, if you change a Theme colorScheme color from Colors.deepPurple to Colors.red and run “flutter test“, the test should fail.
Golden tests are helpful to check that your widgets look as expected. It doesn’t have to be the whole screen. You can create your Golden test for a part of UI as well. If in a while you change your UI, don’t forget to generate new images 😉
Underhood
When you generate images, LocalFileComparator (the default Golden File comparator) is used to create/update the files on disk to match the rendering. When you run a test, LocalFileComparator loads the image file from the local file system and performs a simplistic byte-to-byte comparison of the encoded PNGs. It returns true if there is an exact match. Even though your files represent the same pixels, but are encoded differently, the test will fail.
You can override the default comparator by implementing yours. For this, your comparator needs to extend the class GoldenFileComparator. Then you assign an instance of that class to goldenFileComparator. The code snippet looks like this:
void main() { goldenFileComparator = YourComparator(); testWidgets('Golden test', (WidgetTester tester) async { await tester.pumpWidget(MyApp()); await expectLater( find.byType(MyApp), matchesGoldenFile('main.png'), ); }); } class YourComparator extends GoldenFileComparator { @override Future<bool> compare(Uint8List imageBytes, Uri golden) { // TODO: implement compare throw UnimplementedError(); } @override Future<void> update(Uri golden, Uint8List imageBytes) { // TODO: implement update throw UnimplementedError(); } }
Useful links
Discover more from FutureWare
Subscribe to get the latest posts sent to your email.