Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ very_good test --recursive

# Run tests recursively (shorthand)
very_good test -r

# Run tests on a specific platform
very_good test --platform chrome
```

### [`very_good packages get`](https://cli.vgv.dev/docs/commands/get_pkgs)
Expand Down
27 changes: 23 additions & 4 deletions lib/src/commands/dart/commands/dart_test_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class DartTestOptions {
required this.randomSeed,
required this.optimizePerformance,
required this.forceAnsi,
required this.platform,
required this.rest,
required this.reportOn,
});
Expand All @@ -41,6 +42,7 @@ class DartTestOptions {
: randomOrderingSeed;
final optimizePerformance = argResults['optimization'] as bool;
final forceAnsi = argResults['force-ansi'] as bool?;
final platform = argResults['platform'] as String?;
final reportOn = argResults['report-on'] as String?;
final rest = argResults.rest;

Expand All @@ -54,6 +56,7 @@ class DartTestOptions {
randomSeed: randomSeed,
optimizePerformance: optimizePerformance,
forceAnsi: forceAnsi,
platform: platform,
reportOn: reportOn,
rest: rest,
);
Expand Down Expand Up @@ -87,6 +90,9 @@ class DartTestOptions {
/// default behavior based on stdout and stderr.
final bool? forceAnsi;

/// The platform to run tests on (e.g., 'chrome', 'vm').
final String? platform;

/// An optional file path to report coverage information to.
final String? reportOn;

Expand Down Expand Up @@ -142,13 +148,17 @@ class DartTestCommand extends Command<int> {
..addFlag(
'optimization',
defaultsTo: true,
help: 'Whether to apply optimizations for test performance.',
help:
'Whether to apply optimizations for test performance. '
'Automatically disabled when --platform is specified.',
)
..addOption(
'concurrency',
abbr: 'j',
defaultsTo: '4',
help: 'The number of concurrent test suites run.',
help:
'The number of concurrent test suites run. '
'Automatically set to 1 when --platform is specified.',
)
..addOption(
'tags',
Expand Down Expand Up @@ -190,6 +200,11 @@ class DartTestCommand extends Command<int> {
'An optional file path to report coverage information to. '
'This should be a path relative to the current working directory.',
valueHelp: 'lib/',
)
..addOption(
'platform',
help: 'The platform to run tests on. ',
valueHelp: 'chrome|vm',
);
}

Expand Down Expand Up @@ -231,7 +246,10 @@ This command should be run from the root of your Dart project.''');
final results = await _dartTest(
optimizePerformance:
options.optimizePerformance &&
!TestCLIRunner.isTargettingTestFiles(options.rest),
!TestCLIRunner.isTargettingTestFiles(options.rest) &&
// Disabled optimization when platform is specified
// https://github.com/VeryGoodOpenSource/very_good_cli/issues/1363
options.platform == null,
recursive: recursive,
logger: _logger,
stdout: _logger.write,
Expand All @@ -245,7 +263,8 @@ This command should be run from the root of your Dart project.''');
arguments: [
if (options.excludeTags != null) ...['-x', options.excludeTags!],
if (options.tags != null) ...['-t', options.tags!],
...['-j', options.concurrency],
if (options.platform != null) ...['--platform', options.platform!],
if (options.platform == null) ...['-j', options.concurrency],
...options.rest,
],
reportOn: options.reportOn,
Expand Down
27 changes: 23 additions & 4 deletions lib/src/commands/test/test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class FlutterTestOptions {
required this.forceAnsi,
required this.dartDefine,
required this.dartDefineFromFile,
required this.platform,
required this.rest,
});

Expand All @@ -47,6 +48,7 @@ class FlutterTestOptions {
final dartDefine = argResults['dart-define'] as List<String>?;
final dartDefineFromFile =
argResults['dart-define-from-file'] as List<String>?;
final platform = argResults['platform'] as String?;
final rest = argResults.rest;

return FlutterTestOptions._(
Expand All @@ -62,6 +64,7 @@ class FlutterTestOptions {
forceAnsi: forceAnsi,
dartDefine: dartDefine,
dartDefineFromFile: dartDefineFromFile,
platform: platform,
rest: rest,
);
}
Expand Down Expand Up @@ -104,6 +107,9 @@ class FlutterTestOptions {
/// Optional list of dart define from files
final List<String>? dartDefineFromFile;

/// The platform to run tests on (e.g., 'chrome', 'vm', 'android', 'ios').
final String? platform;

/// The remaining arguments passed to the test command.
final List<String> rest;
}
Expand Down Expand Up @@ -156,13 +162,17 @@ class TestCommand extends Command<int> {
..addFlag(
'optimization',
defaultsTo: true,
help: 'Whether to apply optimizations for test performance.',
help:
'Whether to apply optimizations for test performance. '
'Automatically disabled when --platform is specified.',
)
..addOption(
'concurrency',
abbr: 'j',
defaultsTo: '4',
help: 'The number of concurrent test suites run.',
help:
'The number of concurrent test suites run. '
'Automatically set to 1 when --platform is specified.',
)
..addOption(
'tags',
Expand Down Expand Up @@ -227,6 +237,11 @@ class TestCommand extends Command<int> {
'Entries from "--dart-define" with identical keys take '
'precedence over entries from these files.',
valueHelp: 'use-define-config.json|.env',
)
..addOption(
'platform',
help: 'The platform to run tests on. ',
valueHelp: 'chrome|vm|android|ios',
);
}

Expand Down Expand Up @@ -271,7 +286,10 @@ This command should be run from the root of your Flutter project.''');
optimizePerformance:
options.optimizePerformance &&
!TestCLIRunner.isTargettingTestFiles(options.rest) &&
!options.updateGoldens,
!options.updateGoldens &&
// Disabled optimization when platform is specified
// https://github.com/VeryGoodOpenSource/very_good_cli/issues/1363
options.platform == null,
recursive: recursive,
logger: _logger,
stdout: _logger.write,
Expand All @@ -286,12 +304,13 @@ This command should be run from the root of your Flutter project.''');
if (options.excludeTags != null) ...['-x', options.excludeTags!],
if (options.tags != null) ...['-t', options.tags!],
if (options.updateGoldens) '--update-goldens',
if (options.platform != null) ...['--platform', options.platform!],
if (options.dartDefine != null)
for (final value in options.dartDefine!) '--dart-define=$value',
if (options.dartDefineFromFile != null)
for (final value in options.dartDefineFromFile!)
'--dart-define-from-file=$value',
...['-j', options.concurrency],
if (options.platform == null) ...['-j', options.concurrency],
'--no-pub',
...options.rest,
],
Expand Down
1 change: 1 addition & 0 deletions site/docs/commands/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ very_good test [arguments]
--test-randomize-ordering-seed The seed to randomize the execution order of test cases within test files.
--update-goldens Whether "matchesGoldenFile()" calls within your test methods should update the golden files.
--force-ansi Whether to force ansi output. If not specified, it will maintain the default behavior based on stdout and stderr.
--platform The platform to run tests on. For Flutter tests, this can be "chrome", "vm", "android", "ios", etc. For Dart tests, this can be "chrome", "vm", etc.
--dart-define=<foo=bar> Additional key-value pairs that will be available as constants from the String.fromEnvironment, bool.fromEnvironment, int.fromEnvironment, and double.fromEnvironment constructors. Multiple defines can be passed by repeating "--dart-define" multiple times.

Run "very_good help" to see global options.
Expand Down
48 changes: 46 additions & 2 deletions test/src/commands/dart/commands/dart_test_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const expectedTestUsage = [
'-h, --help Print this usage information.\n'
' --coverage Whether to collect coverage information.\n'
'-r, --recursive Run tests recursively for all nested packages.\n'
' --[no-]optimization Whether to apply optimizations for test performance.\n'
' --[no-]optimization Whether to apply optimizations for test performance. Automatically disabled when --platform is specified.\n'
' (defaults to on)\n'
'-j, --concurrency The number of concurrent test suites run.\n'
'-j, --concurrency The number of concurrent test suites run. Automatically set to 1 when --platform is specified.\n'
' (defaults to "4")\n'
'-t, --tags Run only tests associated with the specified tags.\n'
' --exclude-coverage A glob which will be used to exclude files that match from the coverage.\n'
Expand All @@ -38,6 +38,7 @@ const expectedTestUsage = [
' --test-randomize-ordering-seed The seed to randomize the execution order of test cases within test files.\n'
' --force-ansi Whether to force ansi output. If not specified, it will maintain the default behavior based on stdout and stderr.\n'
' --report-on=<lib/> An optional file path to report coverage information to. This should be a path relative to the current working directory.\n'
' --platform=<chrome|vm> The platform to run tests on. \n'
'\n'
'Run "very_good help" to see global options.',
];
Expand Down Expand Up @@ -106,6 +107,7 @@ void main() {
when<dynamic>(() => argResults['recursive']).thenReturn(false);
when<dynamic>(() => argResults['coverage']).thenReturn(false);
when<dynamic>(() => argResults['optimization']).thenReturn(true);
when<dynamic>(() => argResults['platform']).thenReturn(null);
when(() => argResults.rest).thenReturn([]);
});

Expand Down Expand Up @@ -246,6 +248,48 @@ void main() {
).called(1);
});

test('completes normally --platform chrome', () async {
when<dynamic>(() => argResults['platform']).thenReturn('chrome');
final result = await testCommand.run();
expect(result, equals(ExitCode.success.code));
verify(
() => dartTest(
arguments: ['--platform', 'chrome'],
logger: logger,
stdout: logger.write,
stderr: logger.err,
),
).called(1);
});

test('disables optimization when --platform is specified', () async {
when<dynamic>(() => argResults['platform']).thenReturn('chrome');
final result = await testCommand.run();
expect(result, equals(ExitCode.success.code));
verify(
() => dartTest(
arguments: ['--platform', 'chrome'],
logger: logger,
stdout: logger.write,
stderr: logger.err,
),
).called(1);
});

test('disables concurrency when --platform is specified', () async {
when<dynamic>(() => argResults['platform']).thenReturn('chrome');
final result = await testCommand.run();
expect(result, equals(ExitCode.success.code));
verify(
() => dartTest(
arguments: ['--platform', 'chrome'],
logger: logger,
stdout: logger.write,
stderr: logger.err,
),
).called(1);
});

test('completes normally --test-randomize-ordering-seed random', () async {
when<dynamic>(
() => argResults['test-randomize-ordering-seed'],
Expand Down
48 changes: 46 additions & 2 deletions test/src/commands/test/test_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const expectedTestUsage = [
'-h, --help Print this usage information.\n'
' --coverage Whether to collect coverage information.\n'
'-r, --recursive Run tests recursively for all nested packages.\n'
' --[no-]optimization Whether to apply optimizations for test performance.\n'
' --[no-]optimization Whether to apply optimizations for test performance. Automatically disabled when --platform is specified.\n'
' (defaults to on)\n'
'-j, --concurrency The number of concurrent test suites run.\n'
'-j, --concurrency The number of concurrent test suites run. Automatically set to 1 when --platform is specified.\n'
' (defaults to "4")\n'
'-t, --tags Run only tests associated with the specified tags.\n'
' --exclude-coverage A glob which will be used to exclude files that match from the coverage.\n'
Expand All @@ -40,6 +40,7 @@ const expectedTestUsage = [
' --force-ansi Whether to force ansi output. If not specified, it will maintain the default behavior based on stdout and stderr.\n'
' --dart-define=<foo=bar> Additional key-value pairs that will be available as constants from the String.fromEnvironment, bool.fromEnvironment, int.fromEnvironment, and double.fromEnvironment constructors. Multiple defines can be passed by repeating "--dart-define" multiple times.\n'
' --dart-define-from-file=<use-define-config.json|.env> The path of a .json or .env file containing key-value pairs that will be available as environment variables. These can be accessed using the String.fromEnvironment, bool.fromEnvironment, and int.fromEnvironment constructors. Multiple defines can be passed by repeating "--dart-define-from-file" multiple times. Entries from "--dart-define" with identical keys take precedence over entries from these files.\n'
' --platform=<chrome|vm|android|ios> The platform to run tests on. \n'
'\n'
'Run "very_good help" to see global options.',
];
Expand Down Expand Up @@ -108,6 +109,7 @@ void main() {
when<dynamic>(() => argResults['coverage']).thenReturn(false);
when<dynamic>(() => argResults['update-goldens']).thenReturn(false);
when<dynamic>(() => argResults['optimization']).thenReturn(true);
when<dynamic>(() => argResults['platform']).thenReturn(null);
when(() => argResults.rest).thenReturn([]);
});

Expand Down Expand Up @@ -262,6 +264,48 @@ void main() {
).called(1);
});

test('completes normally --platform chrome', () async {
when<dynamic>(() => argResults['platform']).thenReturn('chrome');
final result = await testCommand.run();
expect(result, equals(ExitCode.success.code));
verify(
() => flutterTest(
arguments: ['--platform', 'chrome', '--no-pub'],
logger: logger,
stdout: logger.write,
stderr: logger.err,
),
).called(1);
});

test('disables optimization when --platform is specified', () async {
when<dynamic>(() => argResults['platform']).thenReturn('chrome');
final result = await testCommand.run();
expect(result, equals(ExitCode.success.code));
verify(
() => flutterTest(
arguments: ['--platform', 'chrome', '--no-pub'],
logger: logger,
stdout: logger.write,
stderr: logger.err,
),
).called(1);
});

test('disables concurrency when --platform is specified', () async {
when<dynamic>(() => argResults['platform']).thenReturn('chrome');
final result = await testCommand.run();
expect(result, equals(ExitCode.success.code));
verify(
() => flutterTest(
arguments: ['--platform', 'chrome', '--no-pub'],
logger: logger,
stdout: logger.write,
stderr: logger.err,
),
).called(1);
});

test('completes normally --test-randomize-ordering-seed random', () async {
when<dynamic>(
() => argResults['test-randomize-ordering-seed'],
Expand Down