FlutterFlow offers Run Mode for instant browser previews, Test Mode for live Firestore data testing, Device Preview for responsive checks, and red error badges to catch widget issues. Use these tools together in a test-as-you-build workflow. Share your Run Mode URL to test on real phones without publishing. DevTools console output helps track action logic and variable state.
Testing in FlutterFlow Before You Ship
FlutterFlow gives you several layers of built-in testing that don't require writing a single test file. Run Mode renders your app in a browser so you can click through flows instantly. Test Mode connects to your real Firestore project, letting you test data reads and writes live. Device Preview simulates different screen sizes to catch responsive layout issues. Red badge indicators on the canvas flag broken widget configurations before you ever run the app. Together, these tools let you catch most bugs before your app reaches users.
Prerequisites
- A FlutterFlow project with at least one page built
- Firebase project connected (for Test Mode)
- Basic familiarity with FlutterFlow's canvas and widget tree
Step-by-step guide
Launch Run Mode for Instant Browser Preview
Launch Run Mode for Instant Browser Preview
Click the Run button (triangle play icon) in the top-right toolbar. FlutterFlow compiles your app and opens it in a new browser tab. You can click buttons, fill forms, and navigate between pages exactly as a user would. Run Mode uses simulated data — it does not read from or write to your real Firestore database. This makes it safe to test destructive actions. Use Run Mode after building each new feature to confirm the UI flow works before adding backend logic. You can share the Run Mode URL with teammates or clients for quick feedback without publishing.
Expected result: Your app opens in a new browser tab and you can interact with all pages and navigation flows.
Switch to Test Mode to Test Live Firestore Data
Switch to Test Mode to Test Live Firestore Data
Click the dropdown arrow next to the Run button and select Test Mode. FlutterFlow compiles and deploys your app to a temporary URL connected to your actual Firebase project. Any data you read or write in Test Mode hits your real Firestore database. This is the right mode for validating queries, checking security rules, and testing auth flows. Because real data is involved, avoid running destructive tests in production collections. Create a separate test collection or use a staging Firebase project when possible. Test Mode is also where you validate that Firestore security rules allow the correct reads and writes.
Expected result: Your app loads from a unique URL, authenticated users can sign in, and Firestore data appears in list views and detail pages.
Use Device Preview to Check Responsive Layouts
Use Device Preview to Check Responsive Layouts
In the FlutterFlow canvas, locate the Device Preview toolbar along the top of the canvas area. Use the device selector to switch between phone sizes (iPhone SE, iPhone 14, Pixel 7), tablets, and web breakpoints. Watch how your layouts respond as you switch devices. Widgets with hardcoded pixel widths often break on small screens. Columns set to fixed heights clip content on short devices. Use the Column with Expanded children or set Flex values on your layout children to create flexible layouts. Test on at least a small phone (375px wide), a standard phone (390px wide), and a tablet (768px wide) before shipping.
Expected result: You can see exactly how your UI renders at each device size and identify layout overflow or clipping issues.
Identify and Fix Red Badge Error Indicators
Identify and Fix Red Badge Error Indicators
FlutterFlow displays red circular badge icons on widgets in the widget tree and on the canvas when a widget has a configuration error. Common causes include: a required property left empty, a variable reference that no longer exists, an action referencing a deleted page, or a component parameter that has no value bound. Click the red badge to open the error detail panel, which describes the specific misconfiguration. Fix each error before running the app — unresolved errors often cause runtime crashes or silent failures where actions simply don't execute. Use the Issues panel (accessible from the bottom toolbar) to see a complete list of all errors across your project.
Expected result: All red badges are resolved, the Issues panel shows zero errors, and your app compiles without widget configuration warnings.
Read Console Output via Chrome DevTools
Read Console Output via Chrome DevTools
When your app is running in Run Mode or Test Mode in Chrome, open DevTools with Cmd+Option+J (Mac) or Ctrl+Shift+J (Windows). FlutterFlow custom actions can use debugPrint() calls to log values to the console. You can also see Flutter framework errors logged here when widgets fail to render. Filter by Errors to isolate crash logs. This is especially useful for diagnosing why a Custom Action isn't firing or why an API call returns unexpected data. For Firebase-specific errors, the Network tab shows the exact request and response from Firestore REST calls.
1// Inside a Custom Action, add debug output:2debugPrint('Cart total: ${cartTotal.toString()}');3debugPrint('User ID: ${currentUserUid}');4debugPrint('API response: ${response.statusCode}');Expected result: You can see variable values and action execution logs in the browser console, making it easy to trace logic flow.
Complete working example
1import 'package:flutter/foundation.dart';2import 'package:flutterflow_ui/flutterflow_ui.dart';34/// Custom Action: verifyOrderBeforeCheckout5/// Validates cart data and logs each step for debugging6Future<bool> verifyOrderBeforeCheckout(7 List<dynamic> cartItems,8 double subtotal,9) async {10 if (kDebugMode) {11 debugPrint('=== verifyOrderBeforeCheckout START ===');12 debugPrint('Cart items count: ${cartItems.length}');13 debugPrint('Subtotal: \$$subtotal');14 }1516 // Validate cart is not empty17 if (cartItems.isEmpty) {18 if (kDebugMode) debugPrint('FAIL: Cart is empty');19 return false;20 }2122 // Validate subtotal is positive23 if (subtotal <= 0) {24 if (kDebugMode) debugPrint('FAIL: Invalid subtotal \$$subtotal');25 return false;26 }2728 // Check each item has required fields29 for (int i = 0; i < cartItems.length; i++) {30 final item = cartItems[i];31 if (item['productId'] == null || item['productId'].toString().isEmpty) {32 if (kDebugMode) debugPrint('FAIL: Item $i missing productId');33 return false;34 }35 if (item['quantity'] == null || (item['quantity'] as int) < 1) {36 if (kDebugMode) debugPrint('FAIL: Item $i has invalid quantity');37 return false;38 }39 if (kDebugMode) {40 debugPrint('Item $i OK: ${item["productId"]} x${item["quantity"]}');41 }42 }4344 if (kDebugMode) {45 debugPrint('=== verifyOrderBeforeCheckout PASS ===');46 }47 return true;48}Common mistakes
Why it's a problem: Only testing in Run Mode on a desktop browser
How to avoid: Always open the Run Mode URL on a real phone browser for at least one test session. Use Device Preview to check at 375px and 390px widths on the canvas.
Why it's a problem: Ignoring red error badges and running Test Mode anyway
How to avoid: Open the Issues panel and resolve every error before switching to Test Mode. A zero-error Issues panel is your pre-flight checklist.
Why it's a problem: Testing write operations in Test Mode against production data
How to avoid: Create a separate _test collection in Firestore for Test Mode operations, or connect a staging Firebase project to your FlutterFlow project for testing.
Best practices
- Test after every feature, not just at the end — catching bugs early is 10x faster to fix
- Keep the Issues panel visible in a pinned browser tab while building
- Use Test Mode for any feature that touches Firestore, Auth, or API calls
- Share Run Mode URLs with stakeholders instead of screenshots — they can click through the real flow
- Add debugPrint statements at the start and end of every Custom Action during development
- Test all error states deliberately: empty list, failed API call, unauthenticated user
- Check Device Preview at 375px (small phone) before every major UI change
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I'm building a FlutterFlow app and want to set up a testing process. My app uses Firestore for data, Firebase Auth for login, and has a checkout flow with a Stripe Cloud Function. Walk me through which FlutterFlow testing tool to use at each stage: building the UI, testing auth, testing Firestore reads/writes, and testing the payment flow.
In my FlutterFlow project, add a Custom Action called 'debugLogCartState' that takes a list of cart item documents and logs the product name, quantity, and price for each item using debugPrint wrapped in kDebugMode checks.
Frequently asked questions
What is the difference between Run Mode and Test Mode in FlutterFlow?
Run Mode renders your app with simulated data in a browser — nothing reads from or writes to Firebase. Test Mode compiles and deploys your app to a temporary URL connected to your real Firebase project, so all auth, Firestore reads/writes, and Cloud Functions execute for real.
Can I test on a real phone without publishing to the App Store?
Yes. Copy the Run Mode URL from the browser address bar and open it on any phone's browser. This gives you a real mobile preview without deployment. For native API testing (camera, push notifications), you'll need to download the project and run it via Xcode or Android Studio.
Why does my app work in Run Mode but fail in Test Mode?
Run Mode uses simulated data and skips security checks. Test Mode hits your real Firebase project where Firestore security rules may block reads/writes, API keys may be missing, or auth state differs. Check the browser console in Test Mode for specific error messages.
How do I see print output from Custom Actions?
Open Chrome DevTools (Cmd+Option+J on Mac) while your app runs in Run Mode or Test Mode. Use debugPrint() inside your Custom Action Dart code. Wrap calls in 'if (kDebugMode)' so they're stripped from production builds.
What do the red badge indicators mean on widgets?
Red badges indicate a widget has a configuration error — a required property is missing, a variable reference is broken, or an action points to a deleted page or component. Click the badge to see the specific error. Resolve all badges before testing to avoid silent failures.
How do I test responsive layouts in FlutterFlow?
Use the Device Preview toolbar at the top of the canvas to switch between device sizes. Test at minimum on iPhone SE (375px), iPhone 14 (390px), and iPad (768px). Look for overflowing text, clipped images, and buttons that become too small to tap.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation