Sample project demonstrating how to write and automate golden tests (visual snapshot tests) in Flutter, using the Alchemist package and continuous integration (GitHub Actions, Codemagic, and similar).
A golden is a reference image (a PNG snapshot) of how a widget or screen looks at a given moment. Think of it as the “approved screenshot” of your UI layout.
When you run a golden test:
- Flutter renders the widget in a test environment (no real device required).
- The test captures that render as an image.
- The image is compared pixel by pixel with the golden file already stored in the repo (
test/goldens/ci/). - If the UI changed and the diff exceeds the allowed threshold, the test fails — so accidental layout, color, or structure regressions are caught in CI.
- If you intentionally changed the UI, you regenerate the goldens with
flutter test --update-goldens, review the new PNGs, and commit them.
Golden tests are visual regression tests: they do not replace logic or interaction tests, but they complement them by guarding what users actually see.
| Type | Where | Purpose |
|---|---|---|
| CI goldens | test/goldens/ci/ |
Stable across macOS, Linux, and Windows; text is obscured so fonts do not break CI. These are committed to Git. |
| Platform goldens | test/goldens/<platform>/ |
Readable previews on your machine for debugging. Not committed (output varies by OS). |
Locally, both can be generated. In CI (CI=true, e.g. Codemagic), only CI goldens run.
- A minimal Flutter app with a “Hello, world!” screen
- Alchemist golden tests in
test/golden_test.dart - Reference images under
test/goldens/ci/ - A GitHub Actions workflow for Alchemist CI golden tests on Ubuntu
lib/
main.dart # Sample app (MyHomePage)
test/
flutter_test_config.dart # Alchemist config (CI vs local)
golden_test.dart # Golden tests
goldens/
ci/ # CI reference images (versioned)
.github/workflows/
golden_tests.yml # Pipeline on GitHub Actions
- Flutter SDK
- Git (to version CI golden images)
Install dependencies:
flutter pub getRun all tests:
flutter testRun only golden tests (Alchemist tags them with golden):
flutter test --tags goldenRun only the golden test file:
flutter test test/golden_test.dartSimulate CI locally (only CI goldens, as on Codemagic):
flutter test --dart-define=CI=trueMore readable output in the terminal (lists each test and variant):
flutter test test --reporter expandedOpen the project root folder (the one that contains pubspec.yaml), not only android/ or lib/.
- Open
test/golden_test.dart. - Click Run (▶) next to
void main()or thegroup('Golden Tests')line,
or right-click thetestfolder → Run 'tests in test.dart'.
Running the whole test folder is valid. With Alchemist you should see 4 tests passed (2 golden tests × 2 variants: Windows + CI).
The default run button does not pass --update-goldens or a verbose reporter. For clearer runs, create dedicated configurations:
Run → Edit Configurations… → + → Flutter Test
| Configuration | Test file | Additional run args |
|---|---|---|
| Golden tests | test/golden_test.dart |
--reporter expanded |
| Golden tests (update) | test/golden_test.dart |
--update-goldens --reporter expanded |
| Golden tests (CI only) | test/golden_test.dart |
--dart-define=CI=true --tags golden --reporter expanded |
Use Golden tests day to day (compare only). Use Golden tests (update) after intentional UI changes. Use Golden tests (CI only) to mimic Codemagic locally.
To update goldens from the IDE without a custom configuration, use the Terminal tab:
flutter test test/golden_test.dart --update-goldens --reporter expandedWhen you intentionally change the UI:
flutter test --update-goldensReview the new files under test/goldens/ci/ before committing. Do not pass --update-goldens in CI pipelines — that would always refresh references and hide real regressions.
| Goal | What to do |
|---|---|
| Validate UI against goldens | Run ▶ on test/ or test/golden_test.dart — expect 4 tests passed (2 tests × Windows + CI). |
| See each test name in the log | flutter test test --reporter expanded or a Flutter Test config with that flag. |
| Update images after a UI change | flutter test test/golden_test.dart --update-goldens (or Golden tests (update) run configuration). |
| Inspect PNG files | Open test/goldens/ci/ (committed) and test/goldens/<platform>/ (e.g. windows/ — local only). |
| Verify failures are detected | Follow How to force a real failure (quick test), then update goldens if the change was intentional. |
| Match Codemagic / CI locally | flutter test --dart-define=CI=true --tags golden (only CI variants, 2 tests). |
Use this to confirm that golden tests actually detect UI changes. Run without --update-goldens.
Changing only
MyApp(e.g.primarySwatch: Colors.red) usually does not fail the test, becausetest/golden_test.dartbuilds its ownMaterialAppand does not pumpMyApp. See I changedmain.dartbut tests still pass below.
Affects the MyHomePage golden only.
const Text('Hello, mundo!'), // was 'Hello, world!'Affects the Hello World golden only.
child: Text('Hello, mundo!'), // was 'Hello, world!'Affects the MyHomePage golden (e.g. red AppBar).
child: MaterialApp(
theme: ThemeData(primarySwatch: Colors.red),
home: const MyHomePage(title: 'Golden Test Example'),
),flutter test test/golden_test.dart --reporter expandedOr use your Golden tests run configuration in Android Studio (without --update-goldens).
- Tests should fail with a golden mismatch.
- Review diffs under
test/failures/(ignored by Git). - Restore the code or run
flutter test test/golden_test.dart --update-goldensafter an intentional UI change, then commit updated files intest/goldens/ci/.
If the Run tool window only shows a green Test Results line (or “4 tests passed”) and no obvious file changes, the tests may still have run successfully. Golden tests compare existing PNGs by default; they do not always create new files or open a visual diff when everything passes.
| What you see | What it usually means |
|---|---|
| 4 tests passed in ~1–2 s | Normal for this repo: Hello World + MyHomePage, each with Windows and CI variants. |
| Collapsed tree, no test names | Android Studio summary view. Use --reporter expanded or expand the run log / use a Flutter Test configuration on golden_test.dart. |
goldens/ looks empty in the Project view |
Expand subfolders: test/goldens/ci/ (versioned) and test/goldens/<platform>/ (e.g. windows/ — local only, often not in Git). |
| No new PNGs after Run ▶ | Expected without --update-goldens. Run only validates against committed CI goldens. |
No failures/ folder |
Expected when tests pass. Diffs are written under test/failures/ mainly when a golden fails. |
Confirm in the terminal:
flutter test test --reporter expandedExpected lines:
Golden Tests renders Hello World layout (variant: Windows)
Golden Tests renders Hello World layout (variant: CI)
Golden Tests renders MyHomePage layout (variant: Windows)
Golden Tests renders MyHomePage layout (variant: CI)
All tests passed!
To prove the pipeline end-to-end, follow How to force a real failure (quick test).
The golden file is compared against the widget tree built inside test/golden_test.dart, not against runApp(MyApp()).
Change in main.dart |
Affects golden tests? |
|---|---|
MyApp → theme: ThemeData(primarySwatch: Colors.red) |
No — tests use their own MaterialApp without that theme. |
MyHomePage → text, AppBar color via Theme.of(context), layout |
Partially — only the MyHomePage scenario; not the Hello World scenario. |
main() / runApp |
No — never executed in widget tests. |
See How to force a real failure (quick test) for step-by-step examples.
To test the real app shell (MyApp + theme), wrap the scenario with const MyApp() instead of a bare MaterialApp in golden_test.dart.
If CI golden PNGs are missing from test/goldens/ci/, generate them once:
flutter pub get
flutter test test/golden_test.dart --update-goldensCommit the files under test/goldens/ci/.
Someone may have updated UI and CI goldens. Either align your code with the new images or, if your UI change is correct, regenerate locally and commit updated test/goldens/ci/ after review.
That is an analyzer/SDK setup issue, not Alchemist. Run flutter pub get, point the IDE Flutter SDK to your install (e.g. C:\Android\flutter-sdk), and restart the Dart Analysis Server.
In test/golden_test.dart:
- Hello World —
MaterialAppwith centered “Hello, world!” text. - MyHomePage — the sample screen from
lib/main.dart(AppBar+ centered text).
Each scenario is declared with GoldenTestScenario inside a GoldenTestGroup and executed via goldenTest from Alchemist.
The workflow .github/workflows/golden_tests.yml runs on Ubuntu with Flutter stable (Dart ≥ 3.8, required by Alchemist) on pushes and pull requests to master:
flutter pub get
flutter test --tags golden --dart-define=CI=trueflutter_test_config.dart also reads the CI environment variable when present; the workflow sets both for compatibility.
Commit the reference PNGs under test/goldens/ci/ so CI can compare them. Update goldens locally with --update-goldens; do not regenerate them in CI on every push.
Codemagic sets CI=true automatically. Use a workflow that runs:
flutter pub get
flutter test --tags goldenCI goldens are comparable on Linux or macOS builders. You do not need a Mac-only machine for Alchemist CI goldens (unlike raw matchesGoldenFile with real text).
Example codemagic.yaml script section:
scripts:
- flutter pub get
- flutter test --tags goldenAlchemist golden tests are not meant to run on Firebase Test Lab.
Alchemist / flutter test goldens |
Firebase Test Lab | |
|---|---|---|
| Where it runs | Host machine or CI (VM) | Real devices / emulators in Google’s cloud |
| Test type | Widget tests (flutter test) |
Instrumentation, Robo, or integration tests on device |
| Comparison | PNG golden files in the repo | Screenshots, performance, crashes — different tooling |
Use Alchemist on Codemagic, GitHub Actions, etc. for visual regression of widgets. Use Firebase Test Lab for running the app on many devices (integration tests, smoke tests, Robo). You can use both in the same project for different purposes, but not the same Alchemist golden pipeline on FTL.
| Package | Purpose |
|---|---|
flutter_test |
Flutter test framework |
| alchemist | Golden tests with CI-stable and platform-readable modes |
The app in lib/main.dart shows an AppBar titled “Golden Test Example” and “Hello, world!” centered on screen.
flutter run- Alchemist on pub.dev
- Alchemist — Recommended setup guide
- Flutter — GoldenFileComparator
- Flutter documentation
Sample project for educational purposes. Adapt and reuse as needed.