Migration to Flutter Guide
Discover our battle-tested 21-step framework for a smooth and successful migration to Flutter!

Patrol VS Code Extension - A Better Way to Run and Debug Flutter UI Tests

Oskar Zając - QA Tester at LeanCode
Oskar Zając - QA Automation Engineer at LeanCode
Dec 8, 2025 • 10 min.
Oskar Zając - QA Tester at LeanCode
Oskar Zając
QA Automation Engineer at LeanCode
Free product design tips
Join our Newsletter for Expert Flutter Tips & Product Design Insights from our seasoned team!
What do you do in IT?
By submitting your email you agree to receive the content requested and to LeanCode's Privacy Policy.
or follow us

Patrol has always been about bringing real-world reliability to Flutter apps, but one thing was still missing: a smooth, first-class workflow inside the IDE most Flutter teams rely on. With Patrol growing rapidly and being adopted across complex projects, we knew it was time to bring its power directly into VS Code, and it happened with the Patrol. 4.0.

We are excited to announce the release of the official Patrol extension for Visual Studio Code! It brings the power of Patrol directly into your IDE, transforming how you write, run, and debug Patrol tests. Keep reading to find out more about how it works.

Why did we create it?

Before the Patrol VS Code extension, QA working with Patrol only had the option to run tests from the terminal. Patrol tests appeared in the VS Code Test Explorer alongside unit and widget tests, which wasn’t convenient for either QAs or developers.

To simplify debugging tests

Debugging Patrol tests previously required running the patrol develop command in the terminal and manually typing out the specific path to the test file.

patrol develop -t integration_test/login_test.dart

This process was time-consuming, especially for repositories with a large number of tests. With the extension, all you need to do is click a button on a test in test explorer.

To reduce tool fragmentation

Currently, a typical Patrol developer's workspace is fragmented across a test file, a simulator/emulator, a terminal window, and the Patrol DevTools extension. The new VS Code extension unifies this workflow, removing the need to constantly switch context between code and terminal. It also streamlines the debugging process by allowing you to automate the opening of DevTools for every session.

Patrol VS Code Extension - Features

Test Explorer Integration

The Patrol VS Code extension integrates with the IDE test explorer, allowing you to use all of its features. This includes:

Visual representation of test structure in a dedicated panel

  • Real-time test status (passed, failed, running).
  • Editor integration - clicking on a test navigates to the appropriate location in code.
  • Test filtering and search.
  • Test execution history.

This integration makes Patrol tests feel like a native part of your development workflow, mimicking the experience you expect from standard unit testing tools but optimized for Patrol.

Automatic detection of test files

The extension automatically scans the Flutter project for Patrol test files. By default, it looks for tests located in the patrol_test directory and ending with the test.dart suffix. Both the test directory and the file suffix are fully configurable. You can change them using the test_directory and test_file_suffix parameters in the patrol section of your pubspec.yaml file.

patrol:
 test_directory: integration_test # default: patrol_test
 test_file_suffix: patrol.dart# default: test.dart

Separate "Patrol" section in Test Explorer

All Patrol tests are displayed in a dedicated "Patrol" section in Test Explorer, providing clear separation from other test types in the project (e.g., Dart unit tests). This separation is crucial for larger projects. It prevents Patrol tests from cluttering the view when developers are running unit tests, and vice versa. It allows QAs to focus entirely on the Patrol suite without having to filter through dozens of widget tests.

Separate "Patrol" section in Test Explorer

Support for groups and nested tests

The extension fully supports the hierarchical structure of Patrol tests, including:

- Test groups ( group() ) - displayed as folders in the test tree
- Nested groups - multi-level group hierarchy
- Individual tests - displayed as leaves in the tree

Each level of the hierarchy can be run or debugged independently.

Support for groups and nested tests in Patrol

Green play button for tests

Thanks to the extension, the tests will now show the “Run Test” (with a debug option also available) button right next to each test call in the code. This works for patrolTest calls as well as for your custom wrapper, if you’ve decided to use one.

Keep in mind, however, that regardless of which test you click, Patrol will always execute the entire file. This is a limitation of Patrol’s architecture, so we recommend keeping one test per file for the best experience.

Green play button for tests

Test debugging

Integration with patrol develop command

For debugging tests, the extension uses the patrol develop command. You can start debugging sessions from the “Testing” tab in your IDE, as well as from additional options on the green play button next to test code.

Hot restart button in debug toolbar

During debug sessions, a dedicated Patrol button section appears in the VS Code debug toolbar (last three buttons):

- Hot Restart - restarts the currently running test,
- Stop Test - stops Patrol develop session,
- Open DevTools - opens Flutter DevTools Widget Inspector.

Automatic VS Code debugger attachment

As with other testing tools, you can add breakpoints in tests so that the test flow will stop when using patrol develop. All other debugger tools (pause, continue, step over, step into, step out) are also supported.

Integration with DevTools and Patrol extension

To make life easier, the Patrol extension allows you to inspect your app in two ways. First, whenever you run Patrol develop and the debugger connects to the app, you will be prompted to open Patrol DevTools. You can even select an option to always open it automatically.

Additionally, the debug toolbar includes a dedicated button for the Flutter DevTools Widget Inspector. This allows you to, for example, use select mode, click the desired widget in the app, and the IDE will open a file with that widget. This makes navigating the app code much easier, especially for QAs.

Configurability

Patrol extension allows you to create a set of arguments that will be passed to Patrol commands. From now on, you won’t have to pass flags and other arguments to every Patrol test run.

Additional arguments for Patrol CLI commands

The extension offers flexible configuration of Patrol CLI arguments at three levels:

1. Global arguments (patrol.additionalArgs) - added to all Patrol commands

2. Arguments for patrol test (patrol.test.additionalArgs) - specific to patrol test calls

3. Arguments for patrol develop (patrol.develop.additionalArgs) - specific to patrol develop calls


Example configuration in settings.json:

 "patrol.additionalArgs": ["--verbose"],
 "patrol.develop.additionalArgs": ["--no-uninstall"],
 "patrol.test.additionalArgs": ["--clear-permissions"],

Custom run profiles

The extension allows defining custom test run profiles that appear as additional options in Test Explorer. Each profile can have its own CLI arguments:

 "patrol.customProfiles": {
   "iOS Simulator": {
     "additionalArgs": ["--device", "iPhone 15 Pro"]
   },
   "Android Emulator": {
     "additionalArgs": ["--device", "emulator-5554"]
   },
   "With Coverage": {
     "additionalArgs": ["--coverage"]
   }
 },


Each profile is available in both Run and Debug modes, enabling easy switching between different test configurations.

For example, this allows you to create distinct profiles for dev, staging, and prod flavors, or create specific configurations that mimic your CI/CD pipeline locally. This ensures that when a test fails locally, you can be confident it's a code issue, not an environment mismatch.

Environment variables

The extension allows defining environment variables that are passed to Patrol CLI processes. This can be handy, for example, if you want to override the default value of PATROL_FLUTTER_COMMAND, which is an everyday use case for fvm users.

 "patrol.env": {
   "PATROL_FLUTTER_COMMAND": "fvm flutter"
 }

Dart-Code integration

Developing Visual Studio Code extensions is a process built upon the TypeScript and Node.js ecosystem. In the standard model, plugins communicate with the editor via the exposed VS Code API, running in a separate process known as the Extension Host.

Facing the challenge of integrating Patrol tests with the standard VS Code API, we decided to leverage existing solutions and opted for tight integration with Dart-Code - the official and battle-tested extension for Dart and Flutter.

As Patrol builds on Dart-Code’s public API for analyzer data, project discovery/outlines, SDK resolution, and debugging hooks, running and debugging tests feels similar to standard Flutter workflows.

 const dartExtension = vs.extensions.getExtension<PublicDartExtensionApi>("dart-code.dart-code")

 if (!dartExtension) {
   throw new Error("Dart extension not found")
 }

 const dartExtensionApi = dartExtension.exports

 const testModel = new TestModel({ showSkippedTests: true }, isPathInsideFlutterProject)
 const testDiscoverer = new TestDiscoverer(logger, dartExtensionApi.workspace, testModel)
 context.subscriptions.push(testDiscoverer)

 constvsTestController = newVsCodeTestController(logger, testModel, testDiscoverer, dartExtensionApi.sdks)

How the Test Tree is built and driven

A tree of test suites, groups, and tests is maintained in TestModel. It keeps this tree in sync during discovery and execution, updating node status, duration, and aggregated pass/total counts, deriving labels/descriptions, and pruning stale or deleted nodes. TestModel emits change events for the UI and forwards lifecycle callbacks to listeners like the VS Code TestController.

VsCodeTestController mirrors the TestModel tree as TestItems and updates the UI when the model changes. It delegates discovery to TestDiscoverer and runs/debugs tests by launching TerminalTestRunner, parsing Patrol output, and mapping lifecycle events to VS Code TestRun updates. It also manages debug session context and DevTools actions, and controls presentation.

Discovering tests

TestDiscoverer, responsible for keeping the test tree up to date, requests the current Outline (a live, lightweight structural summary of a Dart file) via Dart-Code’s public API on files change events, then reconstructs tests/groups in TestModel by recognizing common package:test patterns, so the UI reflects current tests as you type or open files. Updates are debounced per file, nodes get accurate ranges and anything not rediscovered is marked and pruned.

Running, debugging, and DevTools

Patrol runs on the device selected by the Patrol CLI, or on the device you explicitly specify with --device in the extension’s config. Attach and DevTools target the VM that Patrol prints in its output.

For debugging, we detect the DevTools URL in Patrol’s output, extract vmServiceUri (URL of the Dart VM Service), and start a “dart” attach session. By switching the VS Code context key on debugging session start, we enable Patrol’s toolbar (Hot Restart, Stop, Open DevTools). DevTools is opened by Dart-Code, so it targets the right VM and follows the user’s DevTools preferences.

const vmServiceUri = new URL(patrolDevToolsUrl).searchParams.get("uri")

if (vmServiceUri) {
 vs.debug.startDebugging(undefined, {
   name: "Patrol Tests",
   request: "attach",
   dartCodeDebugSessionID,
   isPatrolDebugSession: true,
   type: "dart",
   cwd: projectRoot !== undefined ? path.join(projectRoot, getTestDirectory(projectRoot)) :
undefined,
   vmServiceUri,
 })
}

Bringing it all together

The Patrol Visual Studio Code Extension arrives as part of the broader Patrol 4.0 release – a major update that also introduces Patrol Web support and expands what teams can test across platforms. This new extension brings first-class IDE support to Patrol by solving long-standing workflow gaps: no Test Explorer integration, manual terminal-based debugging, and constant tool switching.

Now, Patrol tests are automatically discovered, grouped, and runnable with a single click, with patrol develop debugging, hot-restart controls, DevTools integration, and full configurability built directly into VS Code. Whether you’re testing mobile or the Web, this extension makes working with Patrol smoother, faster, and far more intuitive.

If you need help setting up Patrol in your project or unlocking the full potential of our framework, the LeanCode team, creators of Patrol, offers dedicated support services such as Patrol Setup & Patrol Training and Automating QA processes in your Flutter application.

Free product design tips
Join our Newsletter for Expert Flutter Tips & Product Design Insights from our seasoned team!
What do you do in IT?
By submitting your email you agree to receive the content requested and to LeanCode's Privacy Policy.
or follow us
Meet our expert

How to automate E2E testing in Flutter with Patrol 4.0?

Mateusz Wojtczak / Head of Mobile at LeanCode
Mateusz Wojtczak, Head of Mobile at LeanCode
In this webinar, our Head of Mobile discusses the existing end-to-end (E2E) testing solutions available on the market - their advantages, disadvantages, and limitations. You'll also learn how to set up your E2E testing environment with Patrol 4.0 and how to avoid common mistakes.
Mateusz Wojtczak
Head of Mobile at LeanCode
Mateusz Wojtczak, Head of Mobile at LeanCode
Rate this article
Star 1Star 2Star 3Star 4Star 5
5.00 / 5 Based on 2 reviews

You may also like

Announcing Patrol 4.0 by LeanCode

How Patrol 4.0 Makes Cross-Platform Flutter Testing Possible

Patrol 4.0 is here! By far the biggest update since improvements were made to the test building, it brings support for a web platform, a VS Code extension, a better debugging experience, and many smaller improvements. Let’s dive into the details and the brief backstory behind this release.

Patrol Web support added by LeanCode

Simplifying Flutter Web Testing: Patrol Web

Patrol has reached version 4.0, marking a major milestone. Among the many new features, one stands out in particular: Patrol now supports Web! In this article, you’ll find a rundown of what Patrol Web can do, but also a look behind the scenes: how we designed it, why certain decisions were made, and what it took to bring Patrol’s architecture from mobile into the browser.

Email Testing in Automated Tests - LeanCode

Mastering Email Testing in Automated End-to-End Tests

This article explores effective strategies for testing email-dependent flows in automated end-to-end tests. It covers practical methods from workarounds to tools along with their implementation, pros and cons, and best practices for seamless integration into development pipelines.