Skip to content

Commit

Permalink
Add an integration test to plugin template example (#117062)
Browse files Browse the repository at this point in the history
* Add an integration test to plugin template example

Dart unit tests don't exercise host-side plugin code at all, so the
example tests in the plugin template currently have very little
meaningful coverage. This adds an integration test to the example app
when creating a plugin, so that there's an example of how to actually
test that a complete round-trip plugin call works.

This is done as a separate template that's currently only used by the
plugin template because I don't know what a good example for a
non-plugin case would be that isn't largely just a duplicate of the
widget tests. However, the integration test pre-includes conditionals
around the parts that are plugin-specific so that it can more easily be
expanded to other use cases later (e.g., in
flutter/flutter#68818).

Part of flutter/flutter#82458

* Add integration test to expected dependencies of a plugin app

* Test fixes

* Make an explicit test case
  • Loading branch information
stuartmorgan authored Dec 15, 2022
1 parent b122200 commit f1d157b
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 2 deletions.
4 changes: 4 additions & 0 deletions dev/devicelab/bin/tasks/plugin_dependencies_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ public class DummyPluginAClass {
final List<dynamic> dependencyGraph = jsonContent['dependencyGraph'] as List<dynamic>;
const String kExpectedPluginsDependenciesContent =
'['
'{'
'"name":"integration_test",'
'"dependencies":[]'
'},'
'{'
'"name":"plugin_a",'
'"dependencies":["plugin_b","plugin_c","plugin_d"]'
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_tools/lib/src/commands/create.dart
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ Your $application code is in $relativeAppMain.
templateContext['androidPluginIdentifier'] = androidPluginIdentifier;

generatedCount += await generateApp(
<String>['app', 'app_test_widget'],
<String>['app', 'app_test_widget', 'app_integration_test'],
project.example.directory,
templateContext,
overwrite: overwrite,
Expand Down
4 changes: 4 additions & 0 deletions packages/flutter_tools/templates/app/pubspec.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ dependencies:
cupertino_icons: ^1.0.2

dev_dependencies:
{{#withPlatformChannelPluginHook}}
integration_test:
sdk: flutter
{{/withPlatformChannelPluginHook}}
flutter_test:
sdk: flutter

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// This is a basic Flutter integration test.
{{#withPlatformChannelPluginHook}}
//
// Since integration tests run in a full Flutter application, they can interact
// with the host side of a plugin implementation, unlike Dart unit tests.
{{/withPlatformChannelPluginHook}}
//
// For more information about Flutter integration tests, please see
// https://docs.flutter.dev/cookbook/testing/integration/introduction


import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

{{#withPlatformChannelPluginHook}}
import 'package:{{pluginProjectName}}/{{pluginProjectName}}.dart';
{{/withPlatformChannelPluginHook}}

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
{{#withPlatformChannelPluginHook}}

testWidgets('getPlatformVersion test', (WidgetTester tester) async {
final {{pluginDartClass}} plugin = {{pluginDartClass}}();
final String? version = await plugin.getPlatformVersion();
// The version string depends on the host platform running the test, so
// just assert that some non-empty string is returned.
expect(version?.isNotEmpty, true);
});
{{/withPlatformChannelPluginHook}}
}
2 changes: 2 additions & 0 deletions packages/flutter_tools/templates/template_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@

"templates/app_test_widget/test/widget_test.dart.tmpl",

"templates/app_integration_test/integration_test/plugin_integration_test.dart.tmpl",

"templates/cocoapods/Podfile-ios-objc",
"templates/cocoapods/Podfile-ios-swift",
"templates/cocoapods/Podfile-macos",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ void main() {
}
final List<String> templatePaths = <String>[
globals.fs.path.join('flutter', 'packages', 'flutter_tools', 'templates', 'app'),
globals.fs.path.join('flutter', 'packages', 'flutter_tools', 'templates', 'app_integration_test'),
globals.fs.path.join('flutter', 'packages', 'flutter_tools', 'templates', 'app_shared'),
globals.fs.path.join('flutter', 'packages', 'flutter_tools', 'templates', 'app_test_widget'),
globals.fs.path.join('flutter', 'packages', 'flutter_tools', 'templates', 'cocoapods'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,27 @@ void main() {
),
});

testUsingContext('plugin example app includes an integration test', () async {
await _createAndAnalyzeProject(
projectDir,
<String>['--template=plugin'],
<String>[
'example/integration_test/plugin_integration_test.dart',
],
);
return _runFlutterTest(projectDir.childDirectory('example'));
}, overrides: <Type, Generator>{
Pub: () => Pub.test(
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
usage: globals.flutterUsage,
botDetector: globals.botDetector,
platform: globals.platform,
stdio: mockStdio,
),
});

testUsingContext('kotlin/swift plugin project', () async {
return _createProject(
projectDir,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ void main() {
final PackagesCommand command = await runCommandIn(exampleProjectPath, 'get');
final PackagesGetCommand getCommand = command.subcommands['get']! as PackagesGetCommand;

expect((await getCommand.usageValues).commandPackagesNumberPlugins, 1);
// A plugin example depends on the plugin itself, and integration_test.
expect((await getCommand.usageValues).commandPackagesNumberPlugins, 2);
}, overrides: <Type, Generator>{
Stdio: () => mockStdio,
Pub: () => Pub.test(
Expand Down

0 comments on commit f1d157b

Please sign in to comment.