-
Notifications
You must be signed in to change notification settings - Fork 29.1k
[flutter_tools] Support Integration Tests #76200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
84eb4f9
to
68e8984
Compare
c565fdc
to
29ecbd7
Compare
29ecbd7
to
590ede2
Compare
/// It is up to the device to determine if [entrypointPath] is a precompiled | ||
/// or raw source file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately the abstraction here isn't very ideal.
For flutter_test, we can accept the precompiled dill, or if we move the compiler into FlutterTesterTestDevice
, we can accept Dart source files.
For a raw Device
, it accepts a source file, or a precompiled APK/IPA.
I can't quite think of a way to abstract this better given the awkward compilation of sources that happen in the FlutterTestPlatform
for the flutter_tester
. let me know if there's any better ideas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its OK, provided you document the convention.
@jonahwilliams Let me know if you have any early feedback for this - Most of the problems I've been having here have been resolved. (Still working on adding the tests) |
@@ -23,7 +23,7 @@ import '../test/runner.dart'; | |||
import '../test/test_wrapper.dart'; | |||
import '../test/watcher.dart'; | |||
|
|||
class TestCommand extends FlutterCommand { | |||
class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider extending the description of the test command to describe the difference in behavior between test and integration test commands
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the doc comment for this
/// [entrypointPath] must be a path to an uncompiled source file. | ||
@override | ||
Future<StreamChannel<String>> start(String entrypointPath) async { | ||
final TargetPlatform targetPlatform = await device.targetPlatform; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its worth thinking about how this implementation could be updated in the future to support testing without rebuilding the APK/IPA on each go. For example, by hot restarting the main isolate with the new entrypoint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think we could make flutter_platform.dart
keep track of some sort of mutable state where rebuilding is skipped for subsequent workflows. For the first run we basically do what is here in this PR, and for subsequent runs we would invoke portions of the attach workflow, to attach and then hot restart the application. I can't be sure if it's sufficient without a prototype, but it seems like a reloadExistingApp
boolean parameter here would be sufficient. It's also fine if we want to make breaking changes to the interface here because it's all internal anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds reasonable to me
final vm_service.VmService vmService = await connectToVmService(launchResult.observatoryUri); | ||
|
||
globals.printTrace('test $id: Finding the correct isolate with the integration test service extension'); | ||
final vm_service.IsolateRef isolateRef = await _findExtensionIsolate(vmService); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There may be some timing issues here, since the kIntegrationTestMethod will not be registered until after main finishes, but this may be after the app/isolate has started. There is a waitForExtension method in the resident_runner library that handles this cases, though it doesn't identify the correct Isolate:
Future<void> waitForExtension(vm_service.VmService vmService, String extension) async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would there be issues with the implementation of _findExtensionIsolate
method defined below? It's implementing something similar to the waitForExtension
method (both subscribing to registered extension events as well as querying for current extensions, which should solve the timing issues here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that makes sense - I would prefer trying to reuse the existing helper if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring to make the existing helper reusable here was done in #77220, and just updated this PR to use the helper here.
/// It is up to the device to determine if [entrypointPath] is a precompiled | ||
/// or raw source file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its OK, provided you document the convention.
Sorry for the delay, I was caught up with some other things, and just found some time to clean this PR up and add more tests. It is finally ready for review 🙂 (I also have a follow up PR #79258 to add device lab tests) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this LGTM.
How comfortable do you feel with these changes, do you think we should wait until the next release cut, or until the devicelab test is ready?
As long as the existing flutter test
behavior` is unchanged it should be OK
Canonical paths become lowercased on Windows. This causes less information to be returned from the VM after adding a breakpoint (observe that the UnresolvedSourceLocation does not have a `script` below: bad (at previous commit) ``` {"jsonrpc":"2.0","method":"streamNotify","params":{"streamId":"Debug","event":{"type":"Event","kind":"BreakpointAdded","isolate":{"type":"@isolate","id":"isolates/2153249320239607","name":"main","number":"2153249320239607","isSystemIsolate":false},"timestamp":1617078845364,"breakpoint":{"type":"Breakpoint","fixedId":true,"id":"breakpoints/1","breakpointNumber":1,"resolved":false,"location":{"type":"UnresolvedSourceLocation","scriptUri":"file:///C:/Users/Jia%20Hao/AppData/Local/Temp/flutter_test_expression_eval_test.c001d9de/test/test.dart","line":5}}}}} ``` good (at HEAD) ``` {"jsonrpc":"2.0","method":"streamNotify","params":{"streamId":"Debug","event":{"type":"Event","kind":"BreakpointAdded","isolate":{"type":"@isolate","id":"isolates/2029881360067999","name":"main","number":"2029881360067999","isSystemIsolate":false},"timestamp":1617079201477,"breakpoint":{"type":"Breakpoint","fixedId":true,"id":"breakpoints/1","breakpointNumber":1,"resolved":false,"location":{"type":"UnresolvedSourceLocation","script":{"type":"@script","fixedId":true,"id":"libraries/@22372424/scripts/file%3A%2F%2F%2FC%3A%2FUsers%2FJia%2520Hao%2FAppData%2FLocal%2FTemp%2Fflutter_test_expression_eval_test.17a2bb2c%2Ftest%2Ftest.dart/178816e6d05","uri":"file:///C:/Users/Jia%20Hao/AppData/Local/Temp/flutter_test_expression_eval_test.17a2bb2c/test/test.dart","_kind":"kernel"},"line":5}}}}} ``` This makes the test [1] confused as it keeps waiting forever. [1]: https://github.com/flutter/flutter/blob/e43738824e88827984bbd7a85fdb11e0ef5398c9/packages/flutter_tools/test/integration.shard/expression_evaluation_test.dart#L113
I think it should be fine to land this without waiting for the next release cut. The only change to the normal Also, I figured out how to test the device lab changes locally in #79258 (found an issue and updated this PR to disable port publication like how |
FWIW, I have an open PR in Dart-Code to support this. I don't plan to merge it for the upcoming release (this week) as I wanted to re-test it all once this PR is complete/merged (it also needs some automated tests). I'll likely merge it just after my release though (and I can make a preview build of the extension that includes the changes for testing/using in the meantime). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only have a nit.
LGTM
Co-authored-by: Jonah Williams <jonahwilliams@google.com>
@DanTup sure, no hurry. I'll merge this and then try and patch your change as well to test it out |
Implements https://flutter.dev/go/tool-integration-test-support
Usage
Examples below are not exhaustive. Flags compatible with
flutter test
should work as well.Minor changes:
package:test
runnerFakeDevice
to support mocking aLaunchResult
Upcoming PR
Related issue: #66264