Running flutter driver tests with an already running application

Artur Korobeynyk
5 min readSep 19, 2022

--

If you have a complex application often you will need to run your tests within the application that is already staying in some kind of state by this time. With the flutter integration tests package, it is not possible (or at least I did not figure out yet how to do that). You always need to start your tests along with launching the application. But flutter driver is capable of being attached to an already running application, so that means that your tests can switch between different programming languages and environments while being executed to bring the application to the necessary state, and then you can attach your flutter driver to that app and start your dart tests.

Here is how it is done. Let's start by creating a simple application:

Let's now run the application using the

flutter run

For this tutorial, I am running the application in a mobile device. Flutter will start executing the dart code and for that it will create a Dart Virtual Machine capable of executing the compiled dart code. The virtual machine will stay active for as long as application is running. If application is started in debug or profiling mode, the virtual machine will expose a URL that can be used to connect to it for checking the application behavior and debugging. Check the ADB logs after the app has started

adb logcat -d | less

Search for the line containing ‘The Dart VM service is listening on’. This line will contain URL, port and token that can be used to connect to the dart virtual machine. Because Dart VM is running on the Android mobile device at the moment, in order to access that URL and port we first need to adb forward that. Run in the command line:

adb forward tcp:<port number> tcp:<port number>

Where <port number> is a port that you got from the adb logcat.

Now you can paste the whole URL from the adb logcat into your browser and you will be able to access the Dart observatory tool that is a Dart debugger.

You can play with it but the main point is that we should be able to access it. Flutter driver uses the same URL to connect to the Observatory to be able to execute its commands. The same VM is used by Flutter Dev Tools to provide developers with a piece of more pretty information regarding the running dart application.

But our application is not yet ready for the flutter driver. Do you remember that we need to add a server, flutter driver extension, that will listen to the test commands within the application’s isolate process? To do that, we need to add dev dependencies to our application in pubspec.yaml file

Now we can enable the flutter driver extension in the application. I will do it right away in a current main file for this tutorial:

Now if you run the application, nothing should be changed for you from the application UI perspective but it will contain a listener process that can be used by Flutter Driver to send commands to the application through the Observatory dart debugger.

Now let's write a flutter driver test. The old tutorials tell you to create tests in specific folders with specific names. That is not something that I call flexible. Instead of the old way, we will do it in another way.

FlutterDriver.connect named constructor for Flutter Driver accepts a named parameter dartVmServiceUrl:

It can be used to specify where Flutter Driver should connect to the dart virtual machine. Meaning, that the application may be already running somewhere and you can just point your test file to connect to that application and run test there. To get that URL for the flutter driver you need to get the Dart VM URL from the adb logcat as we did before, replace the ‘http’ protocol in the URL with the ‘ws’ protocol and append the URL with ‘/ws’. So, the final URL would be something like this:

ws://127.0.0.1:43781/959LBNiPG5c=/ws

For that we can create a function:

So it does the same, gets the line with the Dart VM connection, parses it, forwards ports, and returns connection parameters.

Now we can create our flutter driver factory for example like:

After it is done, we can write our test in the same way as we would do in a regular Flutter Driver.

And now you are not bound to any rules except your application must be running already by the time your tests are started. Your tests will automatically get the necessary connection parameters from the ADB logcat and run the flutter driver test for that application.

The same can be done for a web browser-based application. But for that, you will need to create a web driver instance in dart code, get the session id, URI, specs from it and then use those in WebFlutterDriver.connectedTo function. For example, in a function below I get web driver connection parameters from environment variables that are set by running another test that uses Python to create a browser, run through the web app part until it gets to the Flutter Web App and then Python triggers a test that will use the function below to connect Web Flutter Driver to the Web Application written with flutter that is by this time is running in the browser.

--

--