snaptest 0.2.2+1
snaptest: ^0.2.2+1 copied to clipboard
Snap photos in your widget tests.
Snaptest #
See what your widgets look like during testing.

Snaptest is simple: call snap() in any widget test to save a screenshot of what's currently on screen. Perfect for debugging, documentation, and visual regression testing.
Installation #
dart pub add dev:snaptest
The Basics π #
Just call snap() to see your screen #
Add one line to any widget test to see what it looks like:
import 'package:flutter_test/flutter_test.dart';
import 'package:snaptest/snaptest.dart';
testWidgets('My widget test', (tester) async {
await tester.pumpWidget(const MaterialApp(home: MyPage()));
// That's it! Screenshot saved to .snaptest/
await snap();
});
The screenshot gets saved as a PNG file in .snaptest/ using your test name. Great for debugging failing tests or documenting what your widgets actually look like.
Configure your .gitignore #
**/.snaptest/ # Screenshots (usually not committed)
Level Up: Real Rendering π± #
By default, snaptest creates simplified screenshots (blocked text, no images/shadows) for consistency. But you can enable real rendering to see exactly what users see:
testWidgets('Real rendering example', (tester) async {
await tester.pumpWidget(const MaterialApp(home: MyPage()));
await snap(
settings: SnaptestSettings.rendered([
Devices.ios.iPhone16Pro,
Devices.android.samsungGalaxyS20,
]),
);
});
This creates beautiful screenshots with:
- β Real text rendering
- β Actual images
- β Shadows and effects
- β Device frames around the content
- β Multiple device sizes
- β Multiple orientations (portrait and landscape)
Perfect for documentation, design reviews, or showing stakeholders what the app actually looks like.
Level Up: Golden File Testing π― #
Want automated visual regression testing? Enable golden comparison to catch unintended UI changes:
testWidgets('Golden comparison test', (tester) async {
await tester.pumpWidget(const MaterialApp(home: LoginScreen()));
await snap(
matchToGolden: true,
settings: SnaptestSettings.rendered([Devices.ios.iPhone16Pro]),
);
});
This does both:
- Saves a beautiful screenshot with real rendering and device frames to
.snaptest/ - Compares against golden files to fail the test if UI changes unexpectedly
When golden tests fail due to intentional changes, update them:
flutter test --update-goldens
All the Options π οΈ #
Multiple screenshots per test #
testWidgets('User flow', (tester) async {
await tester.pumpWidget(const MaterialApp(home: MyPage()));
await snap('initial_state');
await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();
await snap('after_tap');
});
Capture specific widgets #
await snap(from: find.byKey(const Key('my-card')));
Global settings for all tests #
void main() {
setUpAll(() {
SnaptestSettings.global = SnaptestSettings.rendered([
Devices.ios.iPhone16Pro,
]);
});
// All snap() calls now use iPhone 16 Pro with real rendering
}
Or create a flutter_test_config.dart file to set the global settings.
Dedicated screenshot tests with snapTest #
For tests specifically designed for screenshots, use snapTest instead of testWidgets. It automatically:
- Adds the
snaptesttag for easy filtering - Applies custom settings for the entire test
import 'package:flutter/material.dart';
import 'package:snaptest/snaptest.dart';
snapTest('Login screen looks correct', (tester) async {
await tester.pumpWidget(const MaterialApp(home: LoginScreen()));
await snap(); // Uses the settings from snapTest
});
snapTest(
'Multi-device homepage',
(tester) async {
await tester.pumpWidget(const MaterialApp(home: HomePage()));
await snap('initial');
await tester.tap(find.byIcon(Icons.menu));
await tester.pumpAndSettle();
await snap('menu_open');
},
settings: SnaptestSettings.rendered([
Devices.ios.iPhone16Pro,
Devices.android.samsungGalaxyS20,
]),
);
Run only screenshot tests:
flutter test --tags snaptest
Or exclude them from regular test runs:
flutter test --exclude-tags snaptest
Test multiple orientations #
testWidgets('Responsive design test', (tester) async {
await tester.pumpWidget(const MaterialApp(home: MyPage()));
await snap(
settings: SnaptestSettings.rendered(
devices: [Devices.ios.iPhone16Pro],
orientations: {
Orientation.portrait,
Orientation.landscape,
},
),
);
});
This automatically creates separate screenshots for each orientation:
my_page_iPhone16Pro_portrait.pngmy_page_iPhone16Pro_landscape.png
All snap() parameters #
await snap(
name: 'custom_name', // Custom filename
from: find.byKey(key), // Specific widget to capture
settings: SnaptestSettings(), // Override global settings
goldenPrefix: 'goldens/', // Golden files directory (default: 'goldens/')
matchToGolden: true, // Enable golden file comparison
);
Settings Reference π #
SnaptestSettings options: #
devices: List of devices to test on (default:[WidgetTesterDevice()])orientations: Set of orientations to test (default:{Orientation.portrait})blockText: Whether to block text rendering for consistency (default:true)renderImages: Whether to render actual images (default:false)renderShadows: Whether to render shadows (default:false)includeDeviceFrame: Whether to include device frame around content (default:false)pathPrefix: Directory where screenshots are saved (default:'.snaptest/')
Convenience constructors: #
SnaptestSettings(): Default settings - blocked text, no images/shadows/framesSnaptestSettings.rendered(devices): Real rendering - actual text, images, shadows, and device frames
Helper Scripts π§ #
Clean all screenshots:
dart run snaptest:clean
Clean screenshots from a custom directory:
dart run snaptest:clean my_custom_dir
Assemble screenshots into a single directory:
dart run snaptest:assemble
Assemble screenshots from a custom directory:
dart run snaptest:assemble my_custom_dir
Custom Screenshot Directories #
You can customize where screenshots are saved by setting the pathPrefix in your settings:
testWidgets('Custom directory example', (tester) async {
await tester.pumpWidget(const MaterialApp(home: MyPage()));
await snap(
settings: SnaptestSettings(
pathPrefix: 'my_screenshots/',
// ... other settings
),
);
});
The helper scripts will work with any custom directory name you specify.
Font Rendering π€ #
macOS: SF Pro Fonts (Recommended) #
For the most accurate iOS screenshot rendering on macOS, install Apple's SF Pro fonts:
- Download SF Pro fonts from Apple's developer site
- Install the fonts to
/Library/Fonts(system-wide installation) - Restart your terminal/IDE if needed
With SF Pro fonts installed, loadFontsAndIcons() will automatically use them for Cupertino widgets, making your screenshots match actual iOS rendering more closely.
Without SF Pro fonts on macOS: Snaptest automatically falls back to Roboto fonts for consistency. You'll see a debug message during test runs if the fonts aren't found.
On other platforms (Linux, Windows): Cupertino widgets will always use Roboto fonts as a fallback, since Apple's SF Pro fonts cannot be legally redistributed or used outside of macOS.
Font Limitations #
Due to Flutter's test environment limitations:
- iOS system fonts use SF Pro (if installed on macOS) or Roboto (fallback)
- Google Fonts only work if bundled as local assets (not fetched remotely)
- Custom fonts must be included in your
pubspec.yaml
This ensures consistent screenshots across environments, but may differ slightly from your actual app.