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

How Patrol 4.0 Makes Cross-Platform Flutter Testing Possible

Julia Borkowska, Senior QA Engineer at LeanCode
Julia Borkowska - Senior QA Engineer at LeanCode
Dec 8, 2025 • 10 min.
Julia Borkowska, Senior QA Engineer at LeanCode
Julia Borkowska
Senior QA Engineer at LeanCode

Rating: 5.00 / 5 Based on 11 reviews

Rating: 5.00 / 5 Based on 11 reviews

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, making your Flutter testing with Patrol easier. Let’s dive into the details and the brief backstory behind this release.

Why does this release matter? The bigger story behind Patrol

When we released Patrol 1.0 back in 2022, we honestly didn’t expect what was to follow. It was born out of our frustration and disappointment with existing Flutter integration testing solutions, and we were hoping it would also help other teams overcome the limitations of existing Flutter automated testing.

Now Patrol, developed by our team at LeanCode, has 200K monthly downloads, 1100+ GitHub stars, and has become a go-to solution for Flutter testing for many, from small apps to large enterprises such as Tide, Sennheiser, easyJet, Miles and More, Couchsurfing, Allofresh, and others.

One thing became clear: the Flutter community didn’t just need another testing tool. It needed a reliable, cross-platform, real end-to-end testing framework. The reviews so far confirm that:

Quotes about Patrol framework

That vision is what fueled the work we put into Patrol. Today, we are introducing Patrol 4.0 - our biggest, boldest release yet. This is the story of what’s new.

BTW. We have something extra for you. If you want to learn more about E2E testing and see Patrol 4.0 in action, sign up for our webinar.

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

Testing Flutter on Mobile and Web – introducing Patrol Web

Some time ago, we published a poll on our Discord community server, asking what the next big feature in Patrol should be, and “support for Flutter Web” was one of the top 3 answers. Also, in GH issues where our users can vote for new features and fixes, web support is the most liked issue in the Patrol repository.

These voices helped shape Patrol’s direction – motivating us to work on web integration – and with Patrol 4.0, that moment is finally here. Now users get a truly powerful framework that lets them test cross-platform Flutter apps with Patrol, which works for Mobile and Web.

But nothing comes easy, and adding a web integration turned out to be a challenge – adding a new platform forced us to think about the current architecture of Android and iOS integrations and how Web is a totally different environment than mobile. Luckily, as a result of our work, you can now run the tests you already wrote against the web version of your app – with all the benefits of Patrol! Test isolation, native interactions, extensive logs, readable test results – you name it.

Let’s take a look at a short demo of how it works:

screen
circlecrossrectangletrianglesblock

Curious about how Patrol Web came to life and how it works? Read the full story here.

Nothing is perfect

There’s a catch though – Web doesn’t support develop mode, which means no hot restart and no devtools. You can learn more about the issues we ran into when trying to make it work in our article. We’ll strive to add develop mode in the future, when the blockers are resolved – in the meantime, you can use the test command to run your tests. 

“But hot restart saves so much time! How can I develop my test without it?” you may think. Don’t worry – fortunately, web builds take much less time than mobile builds, and hot restart doesn’t make such a difference in comparison to running the patrol test command. Whereas build time for Android takes anywhere from about a minute to several minutes, and for iOS at least a few minutes, for Web it takes seconds. You can just rerun the test without a big overhead on build time!

Fitting the mold of native interactions

What about native interactions though? If you already have experience with web testing, you know that this platform has drastically different capabilities when it comes to interacting with the browser. On mobile platforms, you can turn on airplane mode to test how your app works offline.

On the Web, there’s no case for that – if you don’t have an internet connection, the browser itself won’t display your page, so there’s nothing to test in such a situation. On the other hand, there are actions you would certainly perform on the web, but not on mobile - for example, clearing cookies. This means we had to separate API for native interactions into parts, but still let users write concise tests without repeating almost the same code for each platform. More on the successor to native can be found further in this article.

The amount of work that had to be done to make this feature come to life is much greater than what we talked about here. To dive deeper into the technical details of this solution, we encourage you to read our article about developing Patrol Web.

Meet VS Code extension – running and debugging tests through IDE 

Enabling teams to test more platforms was only part of the puzzle. We also wanted to make the everyday testing experience smoother and more intuitive. That’s where the new VS Code extension comes in.

About 2 months ago, we published a beta version of our VS Code extension. After beta testing from our users and members of the Patrol team, we’re releasing it as the official version 1.0. Let’s dive into its features and use cases!

Want more details on how the Patrol Visual Studio Code extension works? Read about it here.


Button of confusion

When talking with new users of Patrol, some of them mentioned that they tried to run tests using  the green button in VS Code displayed next to the patrolTest() call. Almost everyone at LeanCode asked about it as well when we were presenting Patrol to them in the early days. We would just answer: “Yeah, it doesn’t work, we didn’t add this button!”. 

First, we thought that maybe we could make it disappear, but we quickly learned that it’s a part of Flutter VS Code extension’s logic – every method annotated as @isTest is marked by the extension as a test, and it shows a green play button next to it. So every patrol test had this button, which only confuses our users – they click it, and something happens, the test is building, but it fails. The Flutter extension was trying to run the Patrol test, but it was not aware of Patrol, so it just ran flutter test on it, which throws up an error.

We could either propose a change to the Flutter extension to disable it for patrolTest, or write our own extension that handles the test running properly.

You already know we chose the second option.

It’s not just about that one green button

The Patrol VS Code extension release brings many features, making your test development smoother.

Apart from running tests by clicking a button, you can:

  • See all Patrol tests next to other tests in your project with passed/failed results. It gives you a high-level view of which parts of your app are covered and which ones are broken.
  • Run a test in develop mode, which also starts a debugging session. Before, the process to connect to the debugger during develop mode was a bit long and definitely not convenient; now it’s a one-click-of-a-button away.
  • Add breakpoints for debugging. This comes in handy when fixing nasty bugs in the tests or the app.
  • Explore the widget tree in the Widget Inspector embedded in VS Code, just like when debugging a Flutter app. No need to switch windows to a web browser from now on! Also, clicking on widgets redirects you to the place in the app's code where they are implemented. It simplifies the process of adding keys to the widgets in your app, which is one of the more time-consuming parts of test writing.

The extension is available for VS Code users in the Marketplace, and in every VS Code-like editor (e.g., Cursor) through the Open VSX Registry.

If you want to learn more about the features and how to start using our extension, there’s another article covering details of this tool.

Platform is the New Native

Improving the developer experience naturally led us to revisit the architecture itself. To truly scale Patrol into the next generation, we needed a more unified way to work with the device.

As we mentioned before in the part of the article about Web, we needed to redesign the part of Patrol’s API that lets our users perform interaction with native platforms, e.g., with the operating system on the mobile device. The introduction of the web platform helped us to realize that the current solution is not ready for such a different platform, and we have to design an interface that is flexible enough to fit both web and mobile, but still easy to use.

Introducing – platform.

But what’s changing anyway?

Before the change, usage of native API looked like this:

await $.native.openNotifications();

Now, when our users can write tests for Web, it’s a bit confusing that you can write the same code that will compile without errors, but will throw up some kind of error, or will just do nothing when the test is run on Web. This problem also happens in the reverse situation – on Web, you can call a method to clear cookies, which shouldn’t be available on other platforms.

We decided to split this bag of native interactions into 5 categories: Android, iOS, Web, mobile, and platform.

At first, it may look like a rather weird choice, especially for mobile and platform. Let’s see how all these categories come together.

Platform is the New Native in Patrol framweork

Going from the top, platform provides all the other categories and is equivalent to the old native. It also provides a few actions that are common to all of the platforms, such as tap or enterText. The platform-specific categories – Web, Android and iOS – provide only those actions that you can perform on the corresponding platform and only those. That means you have to explicitly write in your tests which platform you expect this action to be performed on.

There is a flaw in this split though – in the old native, you could write one test for both Android and iOS. We want you to be able to do it in the new design as well – mobile solves this issue.

In mobile, you can find all the actions that you can perform on both Android and iOS. There are still some actions available only on one of them;, for example, pressBack is Android-only. mobile is useful if you want to write one test for both mobile platforms, and android and ios make test code clearer.

Since the web is so different in terms of available actions to perform, there’s no common part between itself and mobile platforms, which is why we had to create mobile instead of placing common actions in platform

But what if you want to write a test just for one platform? We know it happens – some flows can be performed only on one platform, or each platform has its own implementation of a feature. No matter how hard we try to have one cross-platform code for our app, the requirements differ in some places and so the tests should be separate in such cases.

If that’s the case for you, we have an easy solution.

The platform-specific categories – Web, Android and iOS – provide all actions which can be performed on said platform, even if they’re already in mobile or platform. Let’s look at a couple of examples.

// a test which runs on all 3 platforms
await $.platform.tap(/*selector*/);

// a test just for Android and iOS
await $.platform.mobile.tap(/*selector*/);

// a test only for Android
await $.platform.android.tap(/*selector*/);

This means if you want to run a test on just one platform, you can use just one way of performing platform actions – in this example, the last test would use $.platform.android throughout its code. It makes the test easier to read, but still as verbose as it can be.

Another big change in platform is the new selector API. If you are already familiar with native2, which we introduced a while ago, you may know that you can write a native selector per platform and find native elements in a more accurate manner. This API is also available in platform, with a few minor changes and with a new selector type – WebSelector.

We hope you’ll find this new API easy-to-use and more flexible than the previous one. If you want to migrate your test to platform, head on to the migration guide in our docs. But if you want to stay with native for a bit longer, it’s still available in 4.0. Note that both native and native2 are deprecated starting from this release and will be removed in the future.

What else is new in Patrol 4.0 – a basket full of smaller features

Ofcourse, no major release is complete without the dozens of small fixes, improvements, and quality-of-life tweaks that make everyday work feel better – even if they don’t get a headline. 

1. Default test directory renamed to patrol_test.

The new workflow also made it clear that teams need more freedom in how they structure tests. Large apps rarely fit into one directory. Patrol 4.0 gives them room to grow.

Moving patrol tests to a separate directory from Flutter’s integration tests allows us to properly show and run tests in the Patrol VS Code extension. You can also set your own name for the test directory in pubspec.yaml configuration.

2. Adding of --build-name and --build-number flags to test, develop and build commands.

You can use those flags to specify build name and number, like in the flutter run command.

3. Full test isolation for iOS.
Pass --full-isolation flag to test or build command to set if all data should be deleted in between tests. On Android, it overrides clearPackageData setting in build.gradle. For iOS simulators, it uninstalls the app after each test. This flag is not available for physical iOS devices.

4. Interactive device picker.

If you have more than one device available for testing and don’t specify a device in the command, patrol_cli asks you which device to use for testing – just like the flutter run command does.

A more detailed change log is available on pub.dev.


New to Patrol? How Patrol works – summary for those who need the basics

Patrol is a Flutter-first UI testing framework developed by LeanCode. It’s a grey-box solution that enhances Flutter testing tools by enabling seamless interaction with both Flutter widgets and native platform elements, such as permission dialogs, system notifications, and WebViews. It combines a Dart-based test API with platform-level automation, allowing tests to simulate real-world user flows across app and OS layers. Patrol’s custom finder syntax simplifies test writing – using selectors like $(#loginButton) – and makes tests more readable and robust than Flutter’s default find system. 

Choose Patrol in cases where your Flutter app needs realistic, production‑grade end‑to-end (E2E) or integration testing, especially when tests must cross the boundary between Flutter widgets and native platform UI. For example: flows involving OS permission dialogs, authentication via WebView, notifications, or manipulating device settings – all of which standard integration_test or flutter_test struggles with.

If you have never tried Patrol, we have a perfect hands-on in 10 minutes or less, or you can simply go to the Patrol Setup Tutorial.

Summing up our big announcement of Patrol 4.0 – your next steps

Patrol 4.0 brings the most requested features and the biggest usability updates to date. Our mission is to make E2E testing for Flutter apps more reliable and to give you a complete tool for your Flutter testing needs.

Patrol 4.0 is already available, and we’d love to show you what it can do. Sign up for our webinar on E2E testing and Patrol to see the features in action.

And if you’re thinking about bringing Patrol into your company, we’re here to help with Patrol setup and training, or full testing strategies.

Patrol is developed by LeanCode, but it is also open-source and community-driven. Build with us. Test with us. Help define the future of Flutter testing. You can help us in many ways:

  • Give us feedback – create an issue on GitHub or join our Discord to share your thoughts
  • Make a contribution – we are open to pull requests to the Patrol repository on GitHub
  • Star on GitHub or like on pub.dev.
  • Follow a dedicated Patrol account on X.

And of course – don’t forget to update Patrol in your project!

Rate this article
Star 1Star 2Star 3Star 4Star 5
5.00 / 5 Based on 11 reviews

You may also like

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.

Patrol VS Code Extension developed by LeanCode

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

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. Read this article to find out more about how it works.

UI Testing in Flutter by LeanCode

The Role of UI Testing in Large-Scale Applications

We dive into the topic of UI testing in Flutter. Read more about automated UI tests' benefits and available solutions and why UI testing plays a crucial role, especially in large-scale applications.