mirror of
https://github.com/flutter/packages.git
synced 2025-06-27 13:19:06 +08:00
Ensure that integration tests are actually being run (#3857)
Many of our integration tests weren't actually being run on CI because they were in the wrong place and/or missing the driver file, and it seems we've just never noticed. This makes a number of changes: - Ensures that all packages with integration tests also have a driver file in the right location. - Also standardizes the format of those files, as the boilerplate `main()` is available in `integration_test`. - Ensures that all integration_test directories are in the right place. - In a couple of places, removes a duplicate copy of the integration test file. - Makes it an error for a plugin that's not excluded to not have integration tests, so this can't easily happen again. - Adds logging of what's being run and skipped, so if something does go wrong in the future it's easy to determine what from the logs. - Excludes `*_platform_interface` since the logging was (potentially confusingly) reporting that they were skipped because they don't support the current platform. Skipping them is correct, just not for that reason. - Excludes the plugins that currently have no integration tests, with references to issues about adding them. Fixes https://github.com/flutter/flutter/issues/81929
This commit is contained in:
@ -52,23 +52,37 @@ class DriveExamplesCommand extends PluginCommand {
|
|||||||
@override
|
@override
|
||||||
Future<void> run() async {
|
Future<void> run() async {
|
||||||
final List<String> failingTests = <String>[];
|
final List<String> failingTests = <String>[];
|
||||||
|
final List<String> pluginsWithoutTests = <String>[];
|
||||||
final bool isLinux = argResults[kLinux] == true;
|
final bool isLinux = argResults[kLinux] == true;
|
||||||
final bool isMacos = argResults[kMacos] == true;
|
final bool isMacos = argResults[kMacos] == true;
|
||||||
final bool isWeb = argResults[kWeb] == true;
|
final bool isWeb = argResults[kWeb] == true;
|
||||||
final bool isWindows = argResults[kWindows] == true;
|
final bool isWindows = argResults[kWindows] == true;
|
||||||
await for (final Directory plugin in getPlugins()) {
|
await for (final Directory plugin in getPlugins()) {
|
||||||
|
final String pluginName = plugin.basename;
|
||||||
|
if (pluginName.endsWith('_platform_interface') &&
|
||||||
|
!plugin.childDirectory('example').existsSync()) {
|
||||||
|
// Platform interface packages generally aren't intended to have
|
||||||
|
// examples, and don't need integration tests, so silently skip them
|
||||||
|
// unless for some reason there is an example directory.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
print('\n==========\nChecking $pluginName...');
|
||||||
|
if (!(await _pluginSupportedOnCurrentPlatform(plugin, fileSystem))) {
|
||||||
|
print('Not supported for the target platform; skipping.');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int examplesFound = 0;
|
||||||
|
bool testsRan = false;
|
||||||
final String flutterCommand =
|
final String flutterCommand =
|
||||||
const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter';
|
const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter';
|
||||||
for (final Directory example in getExamplesForPlugin(plugin)) {
|
for (final Directory example in getExamplesForPlugin(plugin)) {
|
||||||
|
++examplesFound;
|
||||||
final String packageName =
|
final String packageName =
|
||||||
p.relative(example.path, from: packagesDir.path);
|
p.relative(example.path, from: packagesDir.path);
|
||||||
if (!(await _pluginSupportedOnCurrentPlatform(plugin, fileSystem))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final Directory driverTests =
|
final Directory driverTests =
|
||||||
fileSystem.directory(p.join(example.path, 'test_driver'));
|
fileSystem.directory(p.join(example.path, 'test_driver'));
|
||||||
if (!driverTests.existsSync()) {
|
if (!driverTests.existsSync()) {
|
||||||
// No driver tests available for this example
|
print('No driver tests found for $packageName');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Look for driver tests ending in _test.dart in test_driver/
|
// Look for driver tests ending in _test.dart in test_driver/
|
||||||
@ -160,6 +174,7 @@ Tried searching for the following:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (final String targetPath in targetPaths) {
|
for (final String targetPath in targetPaths) {
|
||||||
|
testsRan = true;
|
||||||
final int exitCode = await processRunner.runAndStream(
|
final int exitCode = await processRunner.runAndStream(
|
||||||
flutterCommand,
|
flutterCommand,
|
||||||
<String>[
|
<String>[
|
||||||
@ -177,6 +192,11 @@ Tried searching for the following:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!testsRan) {
|
||||||
|
pluginsWithoutTests.add(pluginName);
|
||||||
|
print(
|
||||||
|
'No driver tests run for $pluginName ($examplesFound examples found)');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
print('\n\n');
|
print('\n\n');
|
||||||
|
|
||||||
@ -188,6 +208,15 @@ Tried searching for the following:
|
|||||||
throw ToolExit(1);
|
throw ToolExit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pluginsWithoutTests.isNotEmpty) {
|
||||||
|
print('The following plugins did not run any integration tests:');
|
||||||
|
for (final String plugin in pluginsWithoutTests) {
|
||||||
|
print(' * $plugin');
|
||||||
|
}
|
||||||
|
print('If this is intentional, they must be explicitly excluded.');
|
||||||
|
throw ToolExit(1);
|
||||||
|
}
|
||||||
|
|
||||||
print('All driver tests successful!');
|
print('All driver tests successful!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -100,6 +101,7 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -143,6 +145,25 @@ void main() {
|
|||||||
throwsA(const TypeMatcher<ToolExit>()));
|
throwsA(const TypeMatcher<ToolExit>()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('a plugin without any integration test files is reported as an error',
|
||||||
|
() async {
|
||||||
|
createFakePlugin('plugin',
|
||||||
|
withExtraFiles: <List<String>>[
|
||||||
|
<String>['example', 'lib', 'main.dart'],
|
||||||
|
],
|
||||||
|
isAndroidPlugin: true,
|
||||||
|
isIosPlugin: true);
|
||||||
|
|
||||||
|
final Directory pluginExampleDirectory =
|
||||||
|
mockPackagesDir.childDirectory('plugin').childDirectory('example');
|
||||||
|
|
||||||
|
createFakePubspec(pluginExampleDirectory, isFlutter: true);
|
||||||
|
|
||||||
|
await expectLater(
|
||||||
|
() => runCapturingPrint(runner, <String>['drive-examples']),
|
||||||
|
throwsA(const TypeMatcher<ToolExit>()));
|
||||||
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'driving under folder "test_driver" when targets are under "integration_test"',
|
'driving under folder "test_driver" when targets are under "integration_test"',
|
||||||
() async {
|
() async {
|
||||||
@ -168,6 +189,7 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -223,6 +245,8 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
|
'Not supported for the target platform; skipping.',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -255,6 +279,7 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -300,6 +325,8 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
|
'Not supported for the target platform; skipping.',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -332,6 +359,7 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -379,6 +407,8 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
|
'Not supported for the target platform; skipping.',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -411,6 +441,7 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -460,6 +491,8 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
|
'Not supported for the target platform; skipping.',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -492,6 +525,7 @@ void main() {
|
|||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
'\n\n',
|
'\n\n',
|
||||||
'All driver tests successful!',
|
'All driver tests successful!',
|
||||||
]),
|
]),
|
||||||
@ -535,6 +569,29 @@ void main() {
|
|||||||
'drive-examples',
|
'drive-examples',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
output,
|
||||||
|
orderedEquals(<String>[
|
||||||
|
'\n==========\nChecking plugin...',
|
||||||
|
'Not supported for the target platform; skipping.',
|
||||||
|
'\n\n',
|
||||||
|
'All driver tests successful!',
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
print(processRunner.recordedCalls);
|
||||||
|
// Output should be empty since running drive-examples --macos with no macos
|
||||||
|
// implementation is a no-op.
|
||||||
|
expect(processRunner.recordedCalls, <ProcessCall>[]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('platform interface plugins are silently skipped', () async {
|
||||||
|
createFakePlugin('aplugin_platform_interface');
|
||||||
|
|
||||||
|
final List<String> output = await runCapturingPrint(runner, <String>[
|
||||||
|
'drive-examples',
|
||||||
|
]);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
output,
|
output,
|
||||||
orderedEquals(<String>[
|
orderedEquals(<String>[
|
||||||
|
Reference in New Issue
Block a user