mirror of
https://github.com/flutter/flutter
synced 2024-09-12 21:01:59 +00:00
Some test cleanup for flutter_tools. (#90227)
This commit is contained in:
parent
5ab6c7bce1
commit
4315cdcf76
|
@ -278,6 +278,8 @@ Future<void> _runGeneralToolTests() async {
|
||||||
testPaths: <String>[path.join('test', 'general.shard')],
|
testPaths: <String>[path.join('test', 'general.shard')],
|
||||||
enableFlutterToolAsserts: false,
|
enableFlutterToolAsserts: false,
|
||||||
// Detect unit test time regressions (poor time delay handling, etc).
|
// Detect unit test time regressions (poor time delay handling, etc).
|
||||||
|
// This overrides the 15 minute default for tools tests.
|
||||||
|
// See the README.md and dart_test.yaml files in the flutter_tools package.
|
||||||
perTestTimeout: const Duration(seconds: 2),
|
perTestTimeout: const Duration(seconds: 2),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -295,8 +297,6 @@ Future<void> _runWebToolTests() async {
|
||||||
path.join(flutterRoot, 'packages', 'flutter_tools'),
|
path.join(flutterRoot, 'packages', 'flutter_tools'),
|
||||||
forceSingleCore: true,
|
forceSingleCore: true,
|
||||||
testPaths: <String>[path.join('test', 'web.shard')],
|
testPaths: <String>[path.join('test', 'web.shard')],
|
||||||
enableFlutterToolAsserts: true,
|
|
||||||
perTestTimeout: const Duration(minutes: 3),
|
|
||||||
includeLocalEngineEnv: true,
|
includeLocalEngineEnv: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,17 +39,30 @@ $ flutter analyze
|
||||||
As with other parts of the Flutter repository, all changes in behavior [must be
|
As with other parts of the Flutter repository, all changes in behavior [must be
|
||||||
tested](https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#write-test-find-bug).
|
tested](https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#write-test-find-bug).
|
||||||
Tests live under the `test/` subdirectory.
|
Tests live under the `test/` subdirectory.
|
||||||
- Hermetic unit tests of tool internals go under `test/general.shard`.
|
|
||||||
- Tests of tool commands go under `test/commands.shard`. Hermetic tests go under
|
|
||||||
its `hermetic/` subdirectory. Non-hermetic tests go under its `permeable`
|
|
||||||
sub-directory. Avoid adding tests here and prefer writing either a unit test or a full
|
|
||||||
integration test.
|
|
||||||
- Integration tests (e.g. tests that run the tool in a subprocess) go under
|
|
||||||
`test/integration.shard`.
|
|
||||||
|
|
||||||
In general, the tests for the code in a file called `file.dart` should go in a
|
- Hermetic unit tests of tool internals go under `test/general.shard`
|
||||||
file called `file_test.dart` in the subdirectory that matches the behavior of
|
and must run in significantly less than two seconds.
|
||||||
the test.
|
|
||||||
|
- Tests of tool commands go under `test/commands.shard`. Hermetic
|
||||||
|
tests go under its `hermetic/` subdirectory. Non-hermetic tests go
|
||||||
|
under its `permeable` sub-directory. Avoid adding tests here and
|
||||||
|
prefer writing either a unit test or a full integration test.
|
||||||
|
|
||||||
|
- Integration tests (e.g. tests that run the tool in a subprocess) go
|
||||||
|
under `test/integration.shard`.
|
||||||
|
|
||||||
|
- Slow web-related tests go in the `test/web.shard` directory.
|
||||||
|
|
||||||
|
In general, the tests for the code in a file called `file.dart` should
|
||||||
|
go in a file called `file_test.dart` in the subdirectory that matches
|
||||||
|
the behavior of the test.
|
||||||
|
|
||||||
|
The `dart_test.yaml` file configures the timeout for these tests to be
|
||||||
|
15 minutes. The `test.dart` script that is used in CI overrides this
|
||||||
|
to two seconds for the `test/general.shard` directory, to catch
|
||||||
|
behaviour that is unexpectedly slow.
|
||||||
|
|
||||||
|
Please avoid setting any other timeouts.
|
||||||
|
|
||||||
#### Using local engine builds in integration tests
|
#### Using local engine builds in integration tests
|
||||||
|
|
||||||
|
@ -73,29 +86,26 @@ To run all of the unit tests:
|
||||||
$ flutter test test/general.shard
|
$ flutter test test/general.shard
|
||||||
```
|
```
|
||||||
|
|
||||||
The tests in `test/integration.shard` are slower to run than the tests in
|
The tests in `test/integration.shard` are slower to run than the tests
|
||||||
`test/general.shard`. Depending on your development computer, you might
|
in `test/general.shard`. Depending on your development computer, you
|
||||||
want to increase timeouts and limit concurrency. Generally it is easier to run
|
might want to limit concurrency. Generally it is easier to run these
|
||||||
these on CI, or to manually verify the behavior you are changing instead of running
|
on CI, or to manually verify the behavior you are changing instead of
|
||||||
the test.
|
running the test.
|
||||||
|
|
||||||
The integration tests also require the `FLUTTER_ROOT` environment variable
|
The integration tests also require the `FLUTTER_ROOT` environment
|
||||||
to be set. The full invocation to run everything might therefore look something like:
|
variable to be set. The full invocation to run everything might
|
||||||
|
therefore look something like:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ FLUTTER_ROOT=~/path/to/flutter-sdk
|
$ FLUTTER_ROOT=~/path/to/flutter-sdk
|
||||||
$ flutter test --timeout 2x --concurrency 1
|
$ flutter test --concurrency 1
|
||||||
```
|
```
|
||||||
|
|
||||||
This will take about an hour to complete.
|
This may take some time (on the order of an hour). The unit tests
|
||||||
|
alone take much less time (on the order of a minute).
|
||||||
|
|
||||||
To run only the tests in `test/general.shard` (which takes about a minute),
|
You can run the tests in a specific file, e.g.:
|
||||||
in this directory run:
|
|
||||||
```shell
|
|
||||||
$ flutter test test/general.shard
|
|
||||||
```
|
|
||||||
|
|
||||||
To run the tests in a specific file, run:
|
|
||||||
```shell
|
```shell
|
||||||
$ flutter test test/general.shard/utils_test.dart
|
$ flutter test test/general.shard/utils_test.dart
|
||||||
```
|
```
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
# overloaded. For this reason, we set the test timeout to
|
# overloaded. For this reason, we set the test timeout to
|
||||||
# significantly more than it would be by default, and we never set the
|
# significantly more than it would be by default, and we never set the
|
||||||
# timeouts in the tests themselves.
|
# timeouts in the tests themselves.
|
||||||
|
#
|
||||||
|
# For the `test/general.shard` specifically, the `dev/bots/test.dart` script
|
||||||
|
# overrides this, reducing it to only 2000ms. Unit tests must run fast!
|
||||||
timeout: 15m
|
timeout: 15m
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
|
|
|
@ -62,7 +62,7 @@ void main() {
|
||||||
expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
|
expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
|
||||||
|
|
||||||
expect(result.exitCode, 0);
|
expect(result.exitCode, 0);
|
||||||
}, timeout: const Timeout(Duration(minutes: 5)));
|
});
|
||||||
|
|
||||||
testWithoutContext('simple build appbundle all targets succeeds', () async {
|
testWithoutContext('simple build appbundle all targets succeeds', () async {
|
||||||
final DeferredComponentsProject project = DeferredComponentsProject(BasicDeferredComponentsConfig());
|
final DeferredComponentsProject project = DeferredComponentsProject(BasicDeferredComponentsConfig());
|
||||||
|
@ -105,7 +105,7 @@ void main() {
|
||||||
expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
|
expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
|
||||||
|
|
||||||
expect(result.exitCode, 0);
|
expect(result.exitCode, 0);
|
||||||
}, timeout: const Timeout(Duration(minutes: 5)));
|
});
|
||||||
|
|
||||||
testWithoutContext('simple build appbundle no-deferred-components succeeds', () async {
|
testWithoutContext('simple build appbundle no-deferred-components succeeds', () async {
|
||||||
final DeferredComponentsProject project = DeferredComponentsProject(BasicDeferredComponentsConfig());
|
final DeferredComponentsProject project = DeferredComponentsProject(BasicDeferredComponentsConfig());
|
||||||
|
@ -151,7 +151,7 @@ void main() {
|
||||||
expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
|
expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
|
||||||
|
|
||||||
expect(result.exitCode, 0);
|
expect(result.exitCode, 0);
|
||||||
}, timeout: const Timeout(Duration(minutes: 5)));
|
});
|
||||||
|
|
||||||
testWithoutContext('simple build appbundle mismatched golden no-validate-deferred-components succeeds', () async {
|
testWithoutContext('simple build appbundle mismatched golden no-validate-deferred-components succeeds', () async {
|
||||||
final DeferredComponentsProject project = DeferredComponentsProject(MismatchedGoldenDeferredComponentsConfig());
|
final DeferredComponentsProject project = DeferredComponentsProject(MismatchedGoldenDeferredComponentsConfig());
|
||||||
|
@ -198,7 +198,7 @@ void main() {
|
||||||
expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
|
expect(archive.findFile('base/assets/flutter_assets/test_assets/asset1.txt') != null, true);
|
||||||
|
|
||||||
expect(result.exitCode, 0);
|
expect(result.exitCode, 0);
|
||||||
}, timeout: const Timeout(Duration(minutes: 5)));
|
});
|
||||||
|
|
||||||
testWithoutContext('simple build appbundle missing android dynamic feature module fails', () async {
|
testWithoutContext('simple build appbundle missing android dynamic feature module fails', () async {
|
||||||
final DeferredComponentsProject project = DeferredComponentsProject(NoAndroidDynamicFeatureModuleDeferredComponentsConfig());
|
final DeferredComponentsProject project = DeferredComponentsProject(NoAndroidDynamicFeatureModuleDeferredComponentsConfig());
|
||||||
|
|
|
@ -104,5 +104,5 @@ void main() {
|
||||||
continuePollingValue: '',
|
continuePollingValue: '',
|
||||||
matches: equals(vmServiceUri),
|
matches: equals(vmServiceUri),
|
||||||
);
|
);
|
||||||
}, timeout: const Timeout.factor(4));
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,6 @@ String unsafeString = null;
|
||||||
if (targetPlatform == 'ios') '--no-codesign',
|
if (targetPlatform == 'ios') '--no-codesign',
|
||||||
], workingDirectory: projectRoot.path);
|
], workingDirectory: projectRoot.path);
|
||||||
expect(result.exitCode, 0);
|
expect(result.exitCode, 0);
|
||||||
}, timeout: const Timeout(Duration(minutes: 3)));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,6 @@ int x = 'String';
|
||||||
contains("A value of type 'String' can't be assigned to a variable of type 'int'."),
|
contains("A value of type 'String' can't be assigned to a variable of type 'int'."),
|
||||||
);
|
);
|
||||||
expect(result.exitCode, 1);
|
expect(result.exitCode, 1);
|
||||||
}, timeout: const Timeout(Duration(minutes: 3)));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,5 +69,5 @@ void main() {
|
||||||
continuePollingValue: '',
|
continuePollingValue: '',
|
||||||
matches: isNotEmpty,
|
matches: isNotEmpty,
|
||||||
);
|
);
|
||||||
}, timeout: const Timeout.factor(4));
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,5 +90,5 @@ void main() {
|
||||||
'app-release.apk',
|
'app-release.apk',
|
||||||
);
|
);
|
||||||
expect(fileSystem.file(exampleAppApk), exists);
|
expect(fileSystem.file(exampleAppApk), exists);
|
||||||
}, timeout: const Timeout(Duration(minutes: 5)));
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,8 +145,6 @@ void main() {
|
||||||
...getLocalEngineArguments(),
|
...getLocalEngineArguments(),
|
||||||
'clean',
|
'clean',
|
||||||
], workingDirectory: workingDirectory);
|
], workingDirectory: workingDirectory);
|
||||||
}, skip: !platform.isMacOS, // [intended] only makes sense for macos platform.
|
}, skip: !platform.isMacOS); // [intended] only makes sense for macos platform.
|
||||||
timeout: const Timeout(Duration(minutes: 5)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,7 @@
|
||||||
// @dart = 2.8
|
// @dart = 2.8
|
||||||
// This file is ready to transition, just uncomment /*?*/, /*!*/, and /*late*/.
|
// This file is ready to transition, just uncomment /*?*/, /*!*/, and /*late*/.
|
||||||
|
|
||||||
// TODO(gspencergoog): Remove this tag once this test's state leaks/test
|
// This file intentionally assumes the tests run in order.
|
||||||
// dependencies have been fixed.
|
|
||||||
// https://github.com/flutter/flutter/issues/85160
|
|
||||||
// Fails with "flutter test --test-randomize-ordering-seed=1000"
|
|
||||||
@Tags(<String>['no-shuffle'])
|
@Tags(<String>['no-shuffle'])
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
@ -40,7 +37,7 @@ import 'package:pedantic/pedantic.dart';
|
||||||
import 'package:process/process.dart';
|
import 'package:process/process.dart';
|
||||||
|
|
||||||
import '../src/common.dart';
|
import '../src/common.dart';
|
||||||
import 'test_utils.dart' show fileSystem, platform;
|
import 'test_utils.dart' show fileSystem;
|
||||||
|
|
||||||
const ProcessManager processManager = LocalProcessManager();
|
const ProcessManager processManager = LocalProcessManager();
|
||||||
final String flutterRoot = getFlutterRoot();
|
final String flutterRoot = getFlutterRoot();
|
||||||
|
@ -189,7 +186,7 @@ Future<ProcessTestResult> runFlutter(
|
||||||
List<Transition> transitions, {
|
List<Transition> transitions, {
|
||||||
bool debug = false,
|
bool debug = false,
|
||||||
bool logging = true,
|
bool logging = true,
|
||||||
Duration expectedMaxDuration = const Duration(minutes: 10), // must be less than test timeout of 15 minutes!
|
Duration expectedMaxDuration = const Duration(minutes: 10), // must be less than test timeout of 15 minutes! See ../../dart_test.yaml.
|
||||||
}) async {
|
}) async {
|
||||||
final Stopwatch clock = Stopwatch()..start();
|
final Stopwatch clock = Stopwatch()..start();
|
||||||
final Process process = await processManager.start(
|
final Process process = await processManager.start(
|
||||||
|
@ -358,7 +355,7 @@ void main() {
|
||||||
} finally {
|
} finally {
|
||||||
tryToDelete(fileSystem.directory(tempDirectory));
|
tryToDelete(fileSystem.directory(tempDirectory));
|
||||||
}
|
}
|
||||||
}, skip: platform.isWindows); // https://github.com/flutter/flutter/issues/87924
|
}, skip: Platform.isWindows); // [intended] Windows doesn't support sending signals so we don't care if it can store the PID.
|
||||||
|
|
||||||
testWithoutContext('flutter run handle SIGUSR1/2', () async {
|
testWithoutContext('flutter run handle SIGUSR1/2', () async {
|
||||||
final String tempDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_overall_experience_test.').resolveSymbolicLinksSync();
|
final String tempDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_overall_experience_test.').resolveSymbolicLinksSync();
|
||||||
|
@ -622,5 +619,5 @@ void main() {
|
||||||
'',
|
'',
|
||||||
'Application finished.',
|
'Application finished.',
|
||||||
]);
|
]);
|
||||||
}, skip: Platform.isWindows); // TODO(zanderso): Re-enable when this test is reliable on device lab, https://github.com/flutter/flutter/issues/81556
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,6 @@ Matcher containsIgnoringWhitespace(String toSearch) {
|
||||||
@isTest
|
@isTest
|
||||||
void test(String description, FutureOr<void> Function() body, {
|
void test(String description, FutureOr<void> Function() body, {
|
||||||
String? testOn,
|
String? testOn,
|
||||||
Timeout? timeout,
|
|
||||||
dynamic skip,
|
dynamic skip,
|
||||||
List<String>? tags,
|
List<String>? tags,
|
||||||
Map<String, dynamic>? onPlatform,
|
Map<String, dynamic>? onPlatform,
|
||||||
|
@ -162,12 +161,14 @@ void test(String description, FutureOr<void> Function() body, {
|
||||||
});
|
});
|
||||||
return body();
|
return body();
|
||||||
},
|
},
|
||||||
timeout: timeout,
|
|
||||||
skip: skip,
|
skip: skip,
|
||||||
tags: tags,
|
tags: tags,
|
||||||
onPlatform: onPlatform,
|
onPlatform: onPlatform,
|
||||||
retry: retry,
|
retry: retry,
|
||||||
testOn: testOn,
|
testOn: testOn,
|
||||||
|
// We don't support "timeout"; see ../../dart_test.yaml which
|
||||||
|
// configures all tests to have a 15 minute timeout which should
|
||||||
|
// definitely be enough.
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +183,6 @@ void test(String description, FutureOr<void> Function() body, {
|
||||||
@isTest
|
@isTest
|
||||||
void testWithoutContext(String description, FutureOr<void> Function() body, {
|
void testWithoutContext(String description, FutureOr<void> Function() body, {
|
||||||
String? testOn,
|
String? testOn,
|
||||||
Timeout? timeout,
|
|
||||||
dynamic skip,
|
dynamic skip,
|
||||||
List<String>? tags,
|
List<String>? tags,
|
||||||
Map<String, dynamic>? onPlatform,
|
Map<String, dynamic>? onPlatform,
|
||||||
|
@ -194,12 +194,14 @@ void testWithoutContext(String description, FutureOr<void> Function() body, {
|
||||||
contextKey: const _NoContext(),
|
contextKey: const _NoContext(),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
timeout: timeout,
|
|
||||||
skip: skip,
|
skip: skip,
|
||||||
tags: tags,
|
tags: tags,
|
||||||
onPlatform: onPlatform,
|
onPlatform: onPlatform,
|
||||||
retry: retry,
|
retry: retry,
|
||||||
testOn: testOn,
|
testOn: testOn,
|
||||||
|
// We don't support "timeout"; see ../../dart_test.yaml which
|
||||||
|
// configures all tests to have a 15 minute timeout which should
|
||||||
|
// definitely be enough.
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,6 @@ void testUsingContext(
|
||||||
Map<Type, Generator> overrides = const <Type, Generator>{},
|
Map<Type, Generator> overrides = const <Type, Generator>{},
|
||||||
bool initializeFlutterRoot = true,
|
bool initializeFlutterRoot = true,
|
||||||
String testOn,
|
String testOn,
|
||||||
Timeout timeout,
|
|
||||||
bool skip, // should default to `false`, but https://github.com/dart-lang/test/issues/545 doesn't allow this
|
bool skip, // should default to `false`, but https://github.com/dart-lang/test/issues/545 doesn't allow this
|
||||||
}) {
|
}) {
|
||||||
if (overrides[FileSystem] != null && overrides[ProcessManager] == null) {
|
if (overrides[FileSystem] != null && overrides[ProcessManager] == null) {
|
||||||
|
@ -167,7 +166,10 @@ void testUsingContext(
|
||||||
// BotDetector implementation in the overrides.
|
// BotDetector implementation in the overrides.
|
||||||
BotDetector: overrides[BotDetector] ?? () => const FakeBotDetector(true),
|
BotDetector: overrides[BotDetector] ?? () => const FakeBotDetector(true),
|
||||||
});
|
});
|
||||||
}, testOn: testOn, skip: skip, timeout: timeout);
|
}, testOn: testOn, skip: skip);
|
||||||
|
// We don't support "timeout"; see ../../dart_test.yaml which
|
||||||
|
// configures all tests to have a 15 minute timeout which should
|
||||||
|
// definitely be enough.
|
||||||
}
|
}
|
||||||
|
|
||||||
void _printBufferedErrors(AppContext testContext) {
|
void _printBufferedErrors(AppContext testContext) {
|
||||||
|
|
|
@ -12,9 +12,9 @@ import 'package:flutter_tools/src/base/os.dart';
|
||||||
import 'package:flutter_tools/src/base/platform.dart';
|
import 'package:flutter_tools/src/base/platform.dart';
|
||||||
import 'package:flutter_tools/src/web/chrome.dart';
|
import 'package:flutter_tools/src/web/chrome.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../src/common.dart';
|
||||||
import '../../src/fake_process_manager.dart';
|
import '../src/fake_process_manager.dart';
|
||||||
import '../../src/fakes.dart';
|
import '../src/fakes.dart';
|
||||||
|
|
||||||
const List<String> kChromeArgs = <String>[
|
const List<String> kChromeArgs = <String>[
|
||||||
'--disable-background-timer-throttling',
|
'--disable-background-timer-throttling',
|
||||||
|
@ -547,7 +547,7 @@ void main() {
|
||||||
contains('Unable to connect to Chrome debug port:'),
|
contains('Unable to connect to Chrome debug port:'),
|
||||||
);
|
);
|
||||||
expect(logger.errorText, contains('SocketException'));
|
expect(logger.errorText, contains('SocketException'));
|
||||||
}, timeout: const Timeout.factor(2));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Chromium> _testLaunchChrome(String userDataDir, FakeProcessManager processManager, ChromiumLauncher chromeLauncher) {
|
Future<Chromium> _testLaunchChrome(String userDataDir, FakeProcessManager processManager, ChromiumLauncher chromeLauncher) {
|
Loading…
Reference in a new issue