Skip to main content
The patrol develop command enables rapid test development by leveraging Flutter’s Hot Restart feature. Make changes to your tests and see results instantly without rebuilding.

Synopsis

patrol develop --target <test_file> [options]

Description

patrol develop builds your app once, then allows you to iterate quickly on test code using Hot Restart. After the initial build completes, press R to restart your tests with code changes applied instantly. This dramatically speeds up the test development workflow:
  • No rebuilds - Only the initial build is required
  • Instant feedback - Press R to restart with changes
  • Live development - Edit tests and see results immediately
Hot Restart only restarts the Flutter part of your app. Native code changes require a full rebuild.

Basic Usage

Start developing a test

patrol develop --target patrol_test/login_test.dart

Workflow

1

Start develop mode

Run the command with your test file:
patrol develop --target patrol_test/login_test.dart
2

Wait for initial build

The first build takes the usual time. Once complete, the app launches and tests run.
3

Edit your test

Make changes to your test code in your editor.
4

Press R to restart

After Hot Restart activates, press R in the terminal to run your updated tests.
5

Repeat

Continue editing and restarting as needed.

Required Options

--target
string
required
The test file to develop with Hot Restart. Only one target is allowed.
patrol develop --target patrol_test/app_test.dart
Unlike patrol test, the develop command requires exactly one --target and does not support multiple targets.

Device Selection

--device
string
default:"first device"
Specify which device to run on.
patrol develop --target patrol_test/app_test.dart --device "iPhone 15 Pro"
patrol develop --target patrol_test/app_test.dart --device emulator-5554

Build Configuration

Build Mode

--debug
flag
default:"true"
Run in debug mode (default and only supported mode).
patrol develop --target patrol_test/app_test.dart --debug
The --release flag is not supported with develop mode. Hot Restart only works in debug mode.

Flavors

--flavor
string
Build a specific flavor of your app.
patrol develop --target patrol_test/app_test.dart --flavor staging

Build Versioning

--build-name
string
Set custom build name (version).
patrol develop --target patrol_test/app_test.dart --build-name 1.2.3
--build-number
string
Set custom build number (version code).
patrol develop --target patrol_test/app_test.dart --build-number 123

Dart Defines

--dart-define
string
Pass environment variables to your app.
patrol develop --target patrol_test/app_test.dart \
  --dart-define API_URL=https://staging.example.com
--dart-define-from-file
string
Load environment variables from a file.
patrol develop --target patrol_test/app_test.dart \
  --dart-define-from-file config/dev.json

Test Execution Options

--uninstall
flag
default:"true"
Uninstall the app before starting.
patrol develop --target patrol_test/app_test.dart --uninstall
patrol develop --target patrol_test/app_test.dart --no-uninstall
--hide-test-steps
flag
default:"false"
Hide individual test steps from output.
patrol develop --target patrol_test/app_test.dart --hide-test-steps
--clear-test-steps
flag
default:"true"
Clear test steps after each test run.
patrol develop --target patrol_test/app_test.dart --clear-test-steps
--label
flag
default:"true"
Display label overlay on the app.
patrol develop --target patrol_test/app_test.dart --no-label

Platform-Specific Options

Android

--package-name
string
Override the Android package name.
patrol develop --target patrol_test/app_test.dart \
  --package-name com.example.myapp

iOS

--bundle-id
string
Override the iOS bundle identifier.
patrol develop --target patrol_test/app_test.dart \
  --bundle-id com.example.MyApp
--ios
string
default:"latest"
Specify iOS version for simulators.
patrol develop --target patrol_test/app_test.dart --ios 17.5

DevTools Integration

--open-devtools
flag
default:"false"
Automatically open Patrol extension in DevTools when ready.
patrol develop --target patrol_test/app_test.dart --open-devtools

Advanced Options

--test-server-port
number
default:"8081"
Port for the test instrumentation server.
patrol develop --target patrol_test/app_test.dart --test-server-port 9001
--app-server-port
number
default:"8082"
Port for the app under test server.
patrol develop --target patrol_test/app_test.dart --app-server-port 9002
--check-compatibility
flag
default:"true"
Verify dependency compatibility.
patrol develop --target patrol_test/app_test.dart --no-check-compatibility

Examples

# Start developing a test
patrol develop --target patrol_test/login_test.dart

Demo

Watch Hot Restart in action:

Caveats and Limitations

patrol develop is powerful, but it has important limitations to understand.

Flutter vs Native Restart

Flutter apps consist of two parts: native and Flutter. Hot Restart only restarts the Flutter part. When you press R:
  • ✅ Flutter code restarts (your main() runs again)
  • ❌ Native code does NOT restart
  • ❌ App data is NOT cleared
  • ❌ App is NOT uninstalled

Platform Support

Physical iOS devices: Hot Restart is unreliable on physical iOS devices due to a Flutter bug. We recommend using simulators for develop mode.
macOS and Web: These platforms are not currently supported with develop mode.
Supported platforms:
  • ✅ Android emulators
  • ✅ Android physical devices
  • ✅ iOS simulators
  • ❌ iOS physical devices (unreliable)
  • ❌ macOS
  • ❌ Web

State Persistence

Because Hot Restart doesn’t clear app state, you need to handle these scenarios:

Permissions

Once granted, permissions cannot be revoked without killing the app. When the app dies, Hot Restart stops. Workaround: Handle both granted and not-granted states in your tests.
patrol('permission test', (\$) async {
  final status = await checkPermission();
  
  if (status.isGranted) {
    // Already granted, skip request
  } else {
    // Request permission
    await requestPermission();
  }
});

File System

Files created in internal storage persist between Hot Restarts. Workaround: Clean up files at the start or end of your tests.
patrol('file test', (\$) async {
  // Clean up from previous runs
  await clearTestData();
  
  // Your test code
  await createFile('test.txt');
  
  // Clean up for next run
  await clearTestData();
});

Shared Preferences

Data saved to SharedPreferences persists between Hot Restarts. Workaround: Clear preferences in your test setup.
patrol('preferences test', (\$) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.clear();
  
  // Your test code
});

Native State

Native code that runs only on app launch won’t re-execute on Hot Restart. Impact: If your app initializes native SDKs or services on startup, they won’t be re-initialized.

Best Practices

1

Use simulators/emulators

Avoid physical iOS devices. Use iOS simulators or Android emulators for reliable Hot Restart.
2

Clean state in tests

Add cleanup code to handle persisted state between restarts.
patrol('test', (\$) async {
  await cleanupState();
  // test code
});
3

Handle permission states

Write tests that work whether permissions are granted or not.
4

Test with full build

Periodically run patrol test to verify tests work with clean state.

Hot Restart vs Hot Reload

FeatureHot RestartHot Reload
SpeedFast (~1s)Very fast (<1s)
Preserves stateNoYes
Runs main()YesNo
Supported by PatrolYesNo
For more details, see this Stack Overflow answer.

Troubleshooting

Hot Restart not activating

If Hot Restart doesn’t become available:
  1. Wait a few seconds after the app starts
  2. Check terminal for error messages
  3. Ensure you’re using a supported platform (not physical iOS)
  4. Try restarting the develop command

Changes not applying

If pressing R doesn’t apply changes:
  1. Verify your file is saved
  2. Check for compilation errors
  3. Ensure changes are in Flutter code, not native code
  4. Try a full rebuild with patrol test

App crashes on restart

If the app crashes when pressing R:
  1. Check for state-related issues (permissions, files, etc.)
  2. Review native code that may not handle restart well
  3. Add proper cleanup in test setup
  4. Check logs for error details

Build docs developers (and LLMs) love