Skip to content

Commit 8decea0

Browse files
authored
feat(test): performance optimizations (#318)
1 parent 8e5add0 commit 8decea0

File tree

12 files changed

+650
-409
lines changed

12 files changed

+650
-409
lines changed

.github/workflows/very_good_cli.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ jobs:
3838
run: flutter pub run test --run-skipped -t pull-request-only
3939

4040
- name: Run Tests
41-
run: flutter test -x pull-request-only -x e2e --no-pub --coverage --test-randomize-ordering-seed random
41+
run: |
42+
flutter pub global activate coverage
43+
flutter pub run test -j 1 -x pull-request-only -x e2e --coverage=coverage --test-randomize-ordering-seed random && dart run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.packages --report-on=lib
4244
4345
- name: Check Code Coverage
4446
uses: VeryGoodOpenSource/very_good_coverage@v1.2.0

lib/src/cli/cli.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:lcov_parser/lcov_parser.dart';
55
import 'package:mason/mason.dart';
66
import 'package:path/path.dart' as p;
77
import 'package:universal_io/io.dart';
8+
import 'package:very_good_cli/src/commands/test/templates/test_runner_bundle.dart';
89
import 'package:very_good_test_runner/very_good_test_runner.dart';
910

1011
part 'dart_cli.dart';

lib/src/cli/flutter_cli.dart

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,11 @@ class Flutter {
115115
String cwd = '.',
116116
bool recursive = false,
117117
bool collectCoverage = false,
118+
bool optimizePerformance = false,
118119
double? minCoverage,
119120
String? excludeFromCoverage,
120121
List<String>? arguments,
122+
void Function([String?]) Function(String message)? progress,
121123
void Function(String)? stdout,
122124
void Function(String)? stderr,
123125
}) async {
@@ -129,13 +131,41 @@ class Flutter {
129131
}
130132

131133
await _runCommand(
132-
cmd: (cwd) {
134+
cmd: (cwd) async {
133135
void noop(String? _) {}
134-
stdout?.call('Running "flutter test" in ${p.canonicalize(cwd)}...\n');
136+
final target = DirectoryGeneratorTarget(Directory(p.normalize(cwd)));
137+
final workingDirectory = target.dir.absolute.path;
138+
stdout?.call(
139+
'Running "flutter test" in ${p.dirname(workingDirectory)}...\n',
140+
);
141+
142+
if (optimizePerformance) {
143+
final optimizationDone = progress?.call('Optimizing tests');
144+
try {
145+
final generator = await MasonGenerator.fromBundle(testRunnerBundle);
146+
var vars = <String, dynamic>{'package-root': workingDirectory};
147+
await generator.hooks.preGen(
148+
vars: vars,
149+
onVarsChanged: (v) => vars = v,
150+
workingDirectory: workingDirectory,
151+
);
152+
await generator.generate(
153+
target,
154+
vars: vars,
155+
fileConflictResolution: FileConflictResolution.overwrite,
156+
);
157+
} finally {
158+
optimizationDone?.call();
159+
}
160+
}
161+
135162
return _flutterTest(
136163
cwd: cwd,
137164
collectCoverage: collectCoverage,
138-
arguments: arguments,
165+
arguments: [
166+
...?arguments,
167+
if (optimizePerformance) p.join('test', '.test_runner.dart')
168+
],
139169
stdout: stdout ?? noop,
140170
stderr: stderr ?? noop,
141171
);

lib/src/commands/commands.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export 'create/create.dart';
22
export 'packages.dart';
3-
export 'test.dart';
3+
export 'test/test.dart';

lib/src/commands/create/create.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class CreateCommand extends Command<int> {
107107

108108
final Analytics _analytics;
109109
final Logger _logger;
110-
final Future<MasonGenerator> Function(MasonBundle) _generator;
110+
final GeneratorBuilder _generator;
111111

112112
@override
113113
String get description =>

lib/src/commands/test/templates/test_runner_bundle.dart

Lines changed: 58 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,35 @@ import 'package:path/path.dart' as path;
66
import 'package:universal_io/io.dart';
77
import 'package:very_good_cli/src/cli/cli.dart';
88

9+
/// Signature for the [Flutter.installed] method.
10+
typedef FlutterInstalledCommand = Future<bool> Function();
11+
12+
/// Signature for the [Flutter.test] method.
13+
typedef FlutterTestCommand = Future<void> Function({
14+
String cwd,
15+
bool recursive,
16+
bool collectCoverage,
17+
bool optimizePerformance,
18+
double? minCoverage,
19+
String? excludeFromCoverage,
20+
List<String>? arguments,
21+
void Function([String?]) Function(String message)? progress,
22+
void Function(String)? stdout,
23+
void Function(String)? stderr,
24+
});
25+
926
/// {@template test_command}
1027
/// `very_good test` command for running tests.
1128
/// {@endtemplate}
1229
class TestCommand extends Command<int> {
1330
/// {@macro test_command}
14-
TestCommand({Logger? logger}) : _logger = logger ?? Logger() {
31+
TestCommand({
32+
Logger? logger,
33+
FlutterInstalledCommand? flutterInstalled,
34+
FlutterTestCommand? flutterTest,
35+
}) : _logger = logger ?? Logger(),
36+
_flutterInstalled = flutterInstalled ?? Flutter.installed,
37+
_flutterTest = flutterTest ?? Flutter.test {
1538
argParser
1639
..addFlag(
1740
'recursive',
@@ -41,6 +64,8 @@ class TestCommand extends Command<int> {
4164
}
4265

4366
final Logger _logger;
67+
final FlutterInstalledCommand _flutterInstalled;
68+
final FlutterTestCommand _flutterTest;
4469

4570
@override
4671
String get description => 'Run tests in a Dart or Flutter project.';
@@ -56,21 +81,33 @@ class TestCommand extends Command<int> {
5681

5782
@override
5883
Future<int> run() async {
59-
final recursive = _argResults['recursive'] as bool;
6084
final targetPath = path.normalize(Directory.current.absolute.path);
85+
final pubspec = File(path.join(targetPath, 'pubspec.yaml'));
86+
87+
if (!pubspec.existsSync()) {
88+
_logger.err(
89+
'''
90+
Could not find a pubspec.yaml in $targetPath.
91+
This command should be run from the root of your Flutter project.''',
92+
);
93+
return ExitCode.noInput.code;
94+
}
95+
96+
final recursive = _argResults['recursive'] as bool;
6197
final collectCoverage = _argResults['coverage'] as bool;
6298
final minCoverage = double.tryParse(
6399
_argResults['min-coverage'] as String? ?? '',
64100
);
65101
final excludeTags = _argResults['exclude-tags'] as String?;
66-
final isFlutterInstalled = await Flutter.installed();
67-
102+
final isFlutterInstalled = await _flutterInstalled();
68103
final excludeFromCoverage = _argResults['exclude-coverage'] as String?;
69104

70105
if (isFlutterInstalled) {
71106
try {
72-
await Flutter.test(
107+
await _flutterTest(
108+
optimizePerformance: _argResults.rest.isEmpty,
73109
recursive: recursive,
110+
progress: _logger.progress,
74111
stdout: _logger.write,
75112
stderr: _logger.err,
76113
collectCoverage: collectCoverage,
@@ -81,13 +118,6 @@ class TestCommand extends Command<int> {
81118
..._argResults.rest,
82119
],
83120
);
84-
} on PubspecNotFound catch (_) {
85-
_logger.err(
86-
'''
87-
Could not find a pubspec.yaml in $targetPath.
88-
This command should be run from the root of your Flutter project.''',
89-
);
90-
return ExitCode.noInput.code;
91121
} on MinCoverageNotMet catch (e) {
92122
_logger.err(
93123
'''Expected coverage >= ${minCoverage!.toStringAsFixed(2)}% but actual is ${e.coverage.toStringAsFixed(2)}%.''',

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dependencies:
1010
args: ^2.1.0
1111
glob: ^2.0.2
1212
lcov_parser: ^0.1.2
13-
mason: ">=0.1.0-dev.9 <0.1.0-dev.10"
13+
mason: ">=0.1.0-dev.12 <0.1.0-dev.13"
1414
mason_logger: ^0.1.0-dev.6
1515
meta: ^1.3.0
1616
path: ^1.8.0

0 commit comments

Comments
 (0)