Skip to content

Golden File Testing

The term golden file refers to a master image that is considered the true rendering of a given widget, state, application, or other visual representation you have chosen to capture.

Golden tests help catch unintended visual regressions early, ensuring that your UI looks exactly the way you expect across changes. We recommend using Alchemist for golden file testing because it provides a declarative API, handles cross-platform rendering inconsistencies, and makes it straightforward to test multiple widget states in a single test file.

Add Alchemist as a dev dependency:

Terminal window
dart pub add dev:alchemist

Create a flutter_test_config.dart file at the root of your test/ directory to configure Alchemist for your project. This file runs before every test file and lets you set a shared theme and control platform-specific behavior:

import 'dart:async';
import 'package:alchemist/alchemist.dart';
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
const isRunningInCi = bool.fromEnvironment('CI');
return AlchemistConfig.runWithConfig(
config: AlchemistConfig(
platformGoldensConfig: PlatformGoldensConfig(
enabled: !isRunningInCi,
),
),
run: testMain,
);
}

This setup disables platform-specific golden tests in CI, where rendering differences across operating systems can cause false failures. Only CI-safe goldens (which replace text with colored blocks) run in CI, keeping your pipeline stable.

Alchemist generates golden images in a goldens/ directory next to your test files. We recommend tracking only the CI goldens in version control, since platform goldens vary across operating systems:

test/
├── flutter_test_config.dart
├── goldens/
│ ├── ci/ # Tracked in version control
│ ├── macos/ # Platform-specific, not tracked
│ └── linux/ # Platform-specific, not tracked
└── my_widget_golden_test.dart

Add the following to your .gitignore:

Terminal window
test/**/goldens/**/*.*
!test/**/goldens/ci/*.*

Use goldenTest along with GoldenTestGroup and GoldenTestScenario to declare your golden tests. This approach groups multiple widget states into a single golden image, making it easy to review visual changes at a glance.

import 'package:alchemist/alchemist.dart';
import 'package:flutter/material.dart';
void main() {
goldenTest(
'renders correctly',
fileName: 'my_button',
builder: () => GoldenTestGroup(
children: [
GoldenTestScenario(
name: 'default',
child: const MyButton(label: 'Click me'),
),
GoldenTestScenario(
name: 'disabled',
child: const MyButton(label: 'Click me', enabled: false),
),
],
),
);
}

Alchemist supports performing gestures or other setup before the golden image is captured. Use the whilePerforming parameter to simulate interactions like presses, long presses, or scrolls:

goldenTest(
'renders pressed state',
fileName: 'my_button_pressed',
whilePerforming: press(find.byType(MyButton)),
builder: () => GoldenTestGroup(
children: [
GoldenTestScenario(
name: 'pressed',
child: const MyButton(label: 'Click me'),
),
],
),
);

Golden tests should be tagged to make it easier to run them separately from other tests.

goldenTest(
'renders correctly',
fileName: 'my_widget',
builder: () => GoldenTestGroup(
children: [
GoldenTestScenario(
name: 'default',
child: const MyWidget(),
),
],
),
);

To configure a golden test tag across multiple files (or an entire package), create a dart_test.yaml file and add the tag configuration:

tags:
golden:
description: "Tests that compare golden files."

You can then run the tests with the tag golden in isolation, or quickly update the golden files with the --update-goldens flag:

Terminal window
flutter test --tags golden # Run only golden tests
flutter test --tags golden --update-goldens # Update golden files