mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Implement flutter test -j
(#20493)
This commit is contained in:
parent
d3e482eca3
commit
98c117bb38
|
@ -3,12 +3,14 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:args/args.dart';
|
import 'package:args/args.dart';
|
||||||
import 'package:flutter_tools/src/base/common.dart';
|
import 'package:flutter_tools/src/base/common.dart';
|
||||||
import 'package:flutter_tools/src/base/context.dart';
|
import 'package:flutter_tools/src/base/context.dart';
|
||||||
import 'package:flutter_tools/src/base/file_system.dart';
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
import 'package:flutter_tools/src/base/io.dart';
|
import 'package:flutter_tools/src/base/io.dart';
|
||||||
|
import 'package:flutter_tools/src/base/platform.dart';
|
||||||
import 'package:flutter_tools/src/cache.dart';
|
import 'package:flutter_tools/src/cache.dart';
|
||||||
import 'package:flutter_tools/src/context_runner.dart';
|
import 'package:flutter_tools/src/context_runner.dart';
|
||||||
import 'package:flutter_tools/src/dart/package_map.dart';
|
import 'package:flutter_tools/src/dart/package_map.dart';
|
||||||
|
@ -121,6 +123,7 @@ Future<Null> run(List<String> args) async {
|
||||||
enableObservatory: collector != null,
|
enableObservatory: collector != null,
|
||||||
previewDart2: true,
|
previewDart2: true,
|
||||||
precompiledDillPath: dillFile.path,
|
precompiledDillPath: dillFile.path,
|
||||||
|
concurrency: math.max(1, platform.numberOfProcessors - 2),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (collector != null) {
|
if (collector != null) {
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
import '../base/file_system.dart';
|
import '../base/file_system.dart';
|
||||||
|
import '../base/platform.dart';
|
||||||
import '../cache.dart';
|
import '../cache.dart';
|
||||||
import '../runner/flutter_command.dart';
|
import '../runner/flutter_command.dart';
|
||||||
import '../test/coverage_collector.dart';
|
import '../test/coverage_collector.dart';
|
||||||
|
@ -77,7 +79,12 @@ class TestCommand extends FlutterCommand {
|
||||||
negatable: false,
|
negatable: false,
|
||||||
help: 'Whether matchesGoldenFile() calls within your test methods should\n'
|
help: 'Whether matchesGoldenFile() calls within your test methods should\n'
|
||||||
'update the golden files rather than test for an existing match.',
|
'update the golden files rather than test for an existing match.',
|
||||||
);
|
)
|
||||||
|
..addOption('concurrency',
|
||||||
|
abbr: 'j',
|
||||||
|
defaultsTo: math.max<int>(1, platform.numberOfProcessors - 2).toString(),
|
||||||
|
help: 'The number of concurrent test processes to run.',
|
||||||
|
valueHelp: 'jobs');
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -91,10 +98,10 @@ class TestCommand extends FlutterCommand {
|
||||||
await super.validateCommand();
|
await super.validateCommand();
|
||||||
if (!fs.isFileSync('pubspec.yaml')) {
|
if (!fs.isFileSync('pubspec.yaml')) {
|
||||||
throwToolExit(
|
throwToolExit(
|
||||||
'Error: No pubspec.yaml file found in the current working directory.\n'
|
'Error: No pubspec.yaml file found in the current working directory.\n'
|
||||||
'Run this command from the root of your project. Test files must be\n'
|
'Run this command from the root of your project. Test files must be\n'
|
||||||
'called *_test.dart and must reside in the package\'s \'test\'\n'
|
'called *_test.dart and must reside in the package\'s \'test\'\n'
|
||||||
'directory (or one of its subdirectories).');
|
'directory (or one of its subdirectories).');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +115,16 @@ class TestCommand extends FlutterCommand {
|
||||||
final bool startPaused = argResults['start-paused'];
|
final bool startPaused = argResults['start-paused'];
|
||||||
if (startPaused && files.length != 1) {
|
if (startPaused && files.length != 1) {
|
||||||
throwToolExit(
|
throwToolExit(
|
||||||
'When using --start-paused, you must specify a single test file to run.',
|
'When using --start-paused, you must specify a single test file to run.',
|
||||||
exitCode: 1);
|
exitCode: 1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final int jobs = int.tryParse(argResults['concurrency']);
|
||||||
|
if (jobs == null || jobs <= 0 || !jobs.isFinite) {
|
||||||
|
throwToolExit(
|
||||||
|
'Could not parse -j/--concurrency argument. It must be an integer greater than zero.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory workDir;
|
Directory workDir;
|
||||||
|
@ -123,7 +138,7 @@ class TestCommand extends FlutterCommand {
|
||||||
if (files.isEmpty) {
|
if (files.isEmpty) {
|
||||||
throwToolExit(
|
throwToolExit(
|
||||||
'Test directory "${workDir.path}" does not appear to contain any test files.\n'
|
'Test directory "${workDir.path}" does not appear to contain any test files.\n'
|
||||||
'Test files must be in that directory and end with the pattern "_test.dart".'
|
'Test files must be in that directory and end with the pattern "_test.dart".'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,8 +150,7 @@ class TestCommand extends FlutterCommand {
|
||||||
|
|
||||||
final bool machine = argResults['machine'];
|
final bool machine = argResults['machine'];
|
||||||
if (collector != null && machine) {
|
if (collector != null && machine) {
|
||||||
throwToolExit(
|
throwToolExit("The test command doesn't support --machine and coverage together");
|
||||||
"The test command doesn't support --machine and coverage together");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TestWatcher watcher;
|
TestWatcher watcher;
|
||||||
|
@ -161,6 +175,7 @@ class TestCommand extends FlutterCommand {
|
||||||
previewDart2: argResults['preview-dart-2'],
|
previewDart2: argResults['preview-dart-2'],
|
||||||
trackWidgetCreation: argResults['track-widget-creation'],
|
trackWidgetCreation: argResults['track-widget-creation'],
|
||||||
updateGoldens: argResults['update-goldens'],
|
updateGoldens: argResults['update-goldens'],
|
||||||
|
concurrency: jobs,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (collector != null) {
|
if (collector != null) {
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:args/command_runner.dart';
|
import 'package:args/command_runner.dart';
|
||||||
// ignore: implementation_imports
|
import 'package:meta/meta.dart';
|
||||||
import 'package:test/src/executable.dart' as test;
|
import 'package:test/src/executable.dart' as test; // ignore: implementation_imports
|
||||||
|
|
||||||
import '../artifacts.dart';
|
import '../artifacts.dart';
|
||||||
import '../base/common.dart';
|
import '../base/common.dart';
|
||||||
|
@ -21,20 +21,21 @@ import 'watcher.dart';
|
||||||
|
|
||||||
/// Runs tests using package:test and the Flutter engine.
|
/// Runs tests using package:test and the Flutter engine.
|
||||||
Future<int> runTests(
|
Future<int> runTests(
|
||||||
List<String> testFiles, {
|
List<String> testFiles, {
|
||||||
Directory workDir,
|
Directory workDir,
|
||||||
List<String> names = const <String>[],
|
List<String> names = const <String>[],
|
||||||
List<String> plainNames = const <String>[],
|
List<String> plainNames = const <String>[],
|
||||||
bool enableObservatory = false,
|
bool enableObservatory = false,
|
||||||
bool startPaused = false,
|
bool startPaused = false,
|
||||||
bool ipv6 = false,
|
bool ipv6 = false,
|
||||||
bool machine = false,
|
bool machine = false,
|
||||||
bool previewDart2 = false,
|
bool previewDart2 = false,
|
||||||
String precompiledDillPath,
|
String precompiledDillPath,
|
||||||
bool trackWidgetCreation = false,
|
bool trackWidgetCreation = false,
|
||||||
bool updateGoldens = false,
|
bool updateGoldens = false,
|
||||||
TestWatcher watcher,
|
TestWatcher watcher,
|
||||||
}) async {
|
@required int concurrency,
|
||||||
|
}) async {
|
||||||
if (trackWidgetCreation && !previewDart2) {
|
if (trackWidgetCreation && !previewDart2) {
|
||||||
throw new UsageException(
|
throw new UsageException(
|
||||||
'--track-widget-creation is valid only when --preview-dart-2 is specified.',
|
'--track-widget-creation is valid only when --preview-dart-2 is specified.',
|
||||||
|
@ -54,13 +55,7 @@ Future<int> runTests(
|
||||||
testArgs.addAll(<String>['-r', 'compact']);
|
testArgs.addAll(<String>['-r', 'compact']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableObservatory) { // (In particular, for collecting code coverage.)
|
testArgs.add('--concurrency=$concurrency');
|
||||||
// Turn on concurrency, but just barely. This is a trade-off between running
|
|
||||||
// too many tests such that they all time out, and too few tests such that
|
|
||||||
// the tests overall take too much time. The current number is empirically
|
|
||||||
// based on what our infrastructure can handle, which isn't ideal...
|
|
||||||
testArgs.add('--concurrency=2');
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String name in names) {
|
for (String name in names) {
|
||||||
testArgs..add('--name')..add(name);
|
testArgs..add('--name')..add(name);
|
||||||
|
|
Loading…
Reference in a new issue