-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Some examples of things @johnmccutchan and I would like to do, but can't today:
- Background a Flutter app with platform views, force trimmed memory, and then take a screenshot of the result
- Find and interact with native widgets beyond screenshots (tap, read semantics, etc)
- Encourage our team to write and maintain more integration tests, because they are easy to write and fast to iterate on
We should do something about it. A couple of options on the table include:
- Invest more in
flutter_driver, keepingintegration_testmore or less where it is today - Invest more in
integration_test, keepingflutter_drivermore or less where it is today - Either of those, but actually deprecate and work towards removing the other framework
- Something else entirely (maybe some community solution is best and we should invest more in that?)
Outside of Flutter, here are some popular integration test solutions for similar problem spaces:
- Appium; many platforms (including Flutter!), runs on the host.
- Detox; React Native, cross-platform; runs on the host.
- Espresso, Android; runs on the host.
- Selenium WebDriver, Web; runs on the host.
- XCTest, iOS; runs on the device.
- UI Automator, Android; runs on the device.
- EarlGrey, iOS; runs on the device.
Read more about the background of flutter_driver v integration_test
Background
Flutter ships with package:flutter_test, and the accompanying command, flutter test, which runs a headless version of Flutter (called flutter_tester) and runs Dart-based unit/functional tests, called widget tests, in a fake environment where the passage of time is controlled by the tester, with many extension points are stubbed out (like platform channels), and a software-based renderer that is ~mostly platform agnostic (and does not require a GPU, for example).
This workflow provides super fast lightweight tests that are suitable for testing widgets and compositions of widgets. It's possible to interact with the widget(s) under test, observe changes as a result, and even take screenshots and compare them for golden-file testing.
Notably, this fake environment has the following limitations:
- The test runs on a fake device1, and cannot interact with plugins
- The passage of time is tightly controlled by the developer, and doesn't always reflect the real interactions in production
- Platform views do not show up, and cannot be interacted with (as there is no platform) and are missing in screenshots
Flutter also ships with two "integration test" packages, flutter_driver and integration_test, which unfortunately are in a state2 of neither being completed nor deprecated. It would take a lot of words to describe the current state, so instead focusing on some key points:
Flutter Driver
Runs the test script on the host, using a different API (similar to ChromeDriver) than tests authored with flutter_test.
PROs:
- Conceptually simple; a small limited RPC-like API "talks" to a Flutter app running on a device
- Capable of interactions that require a host, i.e. with
adbor forcing a Dart VM GC - Already supports functionality such as screenshots
CONs:
- All interactions must be serializable, meaning
Finders cannot be re-used acrossflutter_testandflutter_driver - All interactions and assertions happen over RPC, leading to additional latency and in some cases, flakiness/synchronization
- Can't (at least today) run on Firebase Testlab or systems that require a single bundled APK (or similar)
Integration Test
PROs:
- Uses largely the same API as
flutter_test - Runs entirely in the same process as the Flutter application/under-test, without RPC or serialization
- Can more easily use a combination of platform channels or FFI to easily "talk" to the native platform
- Is supported by Firebase Testlab and similar systems that require a single bundled APK (or similar), and no driver script
CONs:
- Is, from what I can tell, incomplete (it's not clear we haven't finished migrating to it for a specific reason or not)
- Structurally more difficult to interact with host-side tooling (i.e.
adb, Dart VM, etc)
/cc @goderbauer @tugorez @jonahwilliams
Footnotes
-
It is technically possible to
flutter runaflutter_testand have it run on a real device; however many of the limitations remain. ↩ -
Google employees can also read the internal-only go/flutter-integration-testing. ↩