test
Synopsis
Run integration tests.
patrol testTo see all available options and flags, run patrol test --help.
Description
This command is the one use you'll be using most often.
patrol test does the following things:
- Builds the app under test (AUT) and the instrumentation app
- Installs the AUT and the instrumentation on the selected device
- Runs the tests natively, and reports results back in native format.
Under the hood, it calls Gradle (when testing on Android) and xcodebuild (when
testing on iOS).
Discussion
By default, patrol test runs all integration tests (files ending with
_test.dart located in the patrol_test directory). You can customize the test directory by setting test_directory in your pubspec.yaml under the patrol section.
To run a single test, use --target:
patrol test --target patrol_test/login_test.dartYou can use --target more than once to run multiple tests:
patrol test \
--target patrol_test/login_test.dart \
--target patrol_test/app_test.dartOr alternatively:
patrol test --targets patrol_test/login_test.dart,patrol_test/app_test.dartTest files must end with _test.dart. Otherwise the file is not considered a
test and is not run.
--target and --targets.Tags
You can use tags to run only tests with specific tags.
First specify tags in your patrol tests:
patrol(
'example test with tag',
tags: ['android'],
($) async {
await createApp($);
await $(FloatingActionButton).tap();
expect($(#counterText).text, '1');
},
);
patrol(
'example test with two tags',
tags: ['android', 'ios'],
($) async {
await createApp($);
await $(FloatingActionButton).tap();
expect($(#counterText).text, '1');
},
);Then you can run tests with the tags you specified:
patrol test --tags android
patrol test --tags=android
patrol test --tags='android||ios'
patrol test --tags='(android || ios)'
patrol test --tags='(android && tablet)'You can also use --exclude-tags to exclude tests with specific tags:
patrol test --exclude-tags android
patrol test --exclude-tags='(android||ios)'For comprehensive information about tag syntax, complex expressions, and advanced usage, see the Patrol tags documentation.
Coverage
Coverage collection is currently not supported on macOS.
A debug build is required. Coverage relies on the Dart VM Service (mobile)
or DDC source maps (web), which are only available in debug builds, so
--profile and --release are not supported with --coverage.
To collect coverage from patrol tests, use --coverage.
patrol test --coverageThe LCOV report will be saved to /coverage/patrol_lcov.info.
Additionally, you can exclude certain files from the report using glob patterns and --coverage-ignore option.
For instance,
patrol test --coverage --coverage-ignore="**/*.g.dart"excludes all files ending with .g.dart.
Coverage on the web
Web coverage is collected differently from other platforms, so a couple of things differ:
- Lines are reported as covered or uncovered only, without the per-line hit counts available on other platforms.
- The covered-line set may differ slightly from the same code measured on mobile.
The report format is otherwise identical.
Build versioning
You can specify custom build number and build name using the --build-name and --build-number flags. These work
the same as in Flutter CLI:
--build-name: Version name of the app. (e.g.1.2.3)--build-number: Version code of the app. (e.g.123)
patrol test --build-name=1.2.3 --build-number=123
patrol test --target patrol_test/login_test.dart --build-name=1.2.3 --build-number=123Isolation of test runs
To achieve full isolation between test runs:
- On Android: set
clearPackageDatatotruein yourbuild.gradlefile, - On iOS Simulator: use the
--full-isolationflag
This functionality is experimental on iOS and might be removed in the future releases.
patrol test --full-isolationVideo recording
Record a video of each test case using --record-video:
patrol test --record-videoVideos are saved as .mp4 files in <test-directory>/videos (override with
--video-output-dir). Supported on Android emulators and iOS simulators.
- Physical Android devices may also work, depending on the vendor (some block
screenrecord). - Physical iOS devices are not supported.
--video-sizeand--video-bit-rateapply to Android only.
Recording is skipped on unsupported devices, and the test still runs.
On web, recording is handled by Playwright instead. Use --web-video
(e.g. --web-video=on or retain-on-failure). See the
Playwright videos docs.
Screenshots
Patrol can capture native screenshots on Android — automatically on test failure (opt-in) and on demand from a test:
- Enable failure screenshots by adding
screenshot_on_failure: trueto thepatrolsection of yourpubspec.yaml. - Capture on demand with
await $.takeNativeScreenshot('tag')inside a test.
The capture happens natively (via androidx.test) at the moment of failure,
before teardown, so it shows the actual failing screen. Patrol writes the PNG on
the device to /sdcard/Download/screenshots/<class>/<method>/.
On patrol test, screenshots are pulled to <test-directory>/screenshots after
the run (override with --screenshots-output-dir). On device farms the farm
collects them:
- BrowserStack App Automate: enable the Espresso
debugscreenshots: truecapability; images appear in the Screenshots tab. Also enable build-time test discovery (emit_test_manifest) so each test reports a URL-safe name — BrowserStack can't render screenshot URLs with spaces/commas, which the defaultrunDartTest[...]names contain. - Firebase Test Lab: pass
--directories-to-pull=/sdcard/Download/screenshots.
Android only for now (a no-op on iOS). Works in the patrol build android
APK as well as patrol test.
Default-path naming limitation. On the default (runtime-discovery) path
each test reports runDartTest[<dart test name>], so the screenshot folder
is named from the raw Dart test name. That name may contain spaces/commas
(BrowserStack can't render such URLs) or characters like : and / that
Android's MediaStore rewrites to _ on API 29+, which then no longer
matches the name the farm reports — so the screenshot isn't associated with
the test. Locally (patrol test) this is harmless: the files are still
pulled to <test-directory>/screenshots. For reliable farm screenshots,
use emit_test_manifest: its generated per-test names are identifiers, so
they are both filesystem- and URL-safe.
Web Platform
Patrol supports running tests on Flutter web using Playwright. To run tests on web:
patrol test --device chromeWhen running on web:
- Tests execute in Chromium browser via Playwright
- CLI arguments can be used to configure Playwright
- Test results are generated in
test-results/
Arguments
Playwright configuration is updated with values passed to the command. This allows direct control over Playwright
features such as reporting. To see the full list of supported arguments, run patrol test --help.
Note: Some arguments are not supported on web:
--flavor: Flavors are not supported for Flutter web--uninstall: Not applicable to web platform--clear-permissions: Not applicable to web platform--full-isolation: Not applicable to web platform
Running without rebuilding
When build-time test discovery is enabled
(patrol.emit_test_manifest: true), already-built tests can be re-run without
rebuilding using a separate command — see
patrol test-without-building.
Under the hood
patrol test basically calls patrol build and then runs the built app
binaries. For more info, read docs of patrol build.