Handle missing flutter_test dependency cleanly (#7421)
We now produce a more reasonable error message when we're missing the flutter_test dependency in a test. Also, remove the flutter_tools stack traces when the engine dies. Fixes #6187
This commit is contained in:
parent
2155fb74b6
commit
b9f49a40f7
9
dev/missing_dependency_tests/.gitignore
vendored
Normal file
9
dev/missing_dependency_tests/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
.atom
|
||||
.DS_Store
|
||||
.buildlog
|
||||
.idea
|
||||
.packages
|
||||
.pub/
|
||||
build/
|
||||
packages
|
||||
pubspec.lock
|
4
dev/missing_dependency_tests/pubspec.yaml
Normal file
4
dev/missing_dependency_tests/pubspec.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
name: missing_dependency_tests
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
4
dev/missing_dependency_tests/trivial_expectation.txt
Normal file
4
dev/missing_dependency_tests/trivial_expectation.txt
Normal file
@ -0,0 +1,4 @@
|
||||
<<skip until matching line>>
|
||||
<<stderr>>
|
||||
<<skip until matching line>>
|
||||
Failed to load test harness\. +Are you missing a dependency on flutter_test\?
|
11
dev/missing_dependency_tests/trivial_test.dart
Normal file
11
dev/missing_dependency_tests/trivial_test.dart
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('Trival test', () {
|
||||
expect(42, 42);
|
||||
});
|
||||
}
|
@ -105,7 +105,7 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
subprocessActive = false;
|
||||
if (!controllerSinkClosed && exitCode != 0) {
|
||||
String message = _getErrorMessage(_getExitCodeMessage(exitCode, 'after tests finished'), testPath, shellPath);
|
||||
controller.sink.addError(new Exception(message));
|
||||
controller.sink.addError(message);
|
||||
}
|
||||
});
|
||||
|
||||
@ -127,13 +127,13 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
case _InitialResult.crashed:
|
||||
int exitCode = await process.exitCode;
|
||||
String message = _getErrorMessage(_getExitCodeMessage(exitCode, 'before connecting to test harness'), testPath, shellPath);
|
||||
controller.sink.addError(new Exception(message));
|
||||
controller.sink.addError(message);
|
||||
controller.sink.close();
|
||||
await controller.sink.done;
|
||||
break;
|
||||
case _InitialResult.timedOut:
|
||||
String message = _getErrorMessage('Test never connected to test harness.', testPath, shellPath);
|
||||
controller.sink.addError(new Exception(message));
|
||||
controller.sink.addError(message);
|
||||
controller.sink.close();
|
||||
await controller.sink.done;
|
||||
break;
|
||||
@ -169,7 +169,7 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
int exitCode = await process.exitCode;
|
||||
subprocessActive = false;
|
||||
String message = _getErrorMessage(_getExitCodeMessage(exitCode, 'before test harness closed its WebSocket'), testPath, shellPath);
|
||||
controller.sink.addError(new Exception(message));
|
||||
controller.sink.addError(message);
|
||||
controller.sink.close();
|
||||
await controller.sink.done;
|
||||
break;
|
||||
@ -214,8 +214,12 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
import 'dart:convert';
|
||||
import 'dart:io'; // ignore: dart_io_import
|
||||
|
||||
import 'package:stream_channel/stream_channel.dart';
|
||||
// We import this library first in order to trigger an import error for
|
||||
// package:test (rather than package:stream_channel) when the developer forgets
|
||||
// to add a dependency on package:test.
|
||||
import 'package:test/src/runner/plugin/remote_platform_helpers.dart';
|
||||
|
||||
import 'package:stream_channel/stream_channel.dart';
|
||||
import 'package:test/src/runner/vm/catch_isolate_errors.dart';
|
||||
|
||||
import '$testUrl' as test;
|
||||
@ -285,7 +289,9 @@ void main() {
|
||||
stream.transform(UTF8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.listen((String line) {
|
||||
if (line != null)
|
||||
if (line.startsWith('error: Unable to read Dart source \'package:test/'))
|
||||
printError('\n\nFailed to load test harness. Are you missing a dependency on flutter_test?\n');
|
||||
else if (line != null)
|
||||
printStatus('Shell: $line');
|
||||
});
|
||||
}
|
||||
|
@ -17,23 +17,30 @@ import 'src/context.dart';
|
||||
|
||||
void main() {
|
||||
group('test', () {
|
||||
final String automatedTestsDirectory = path.join('..', '..', 'dev', 'automated_tests');
|
||||
final String flutterTestDirectory = path.join(automatedTestsDirectory, 'flutter_test');
|
||||
|
||||
testUsingContext('TestAsyncUtils guarded function test', () async {
|
||||
Cache.flutterRoot = '../..';
|
||||
return _testFile('test_async_utils_guarded', 1);
|
||||
return _testFile('test_async_utils_guarded', 1, automatedTestsDirectory, flutterTestDirectory);
|
||||
});
|
||||
testUsingContext('TestAsyncUtils unguarded function test', () async {
|
||||
Cache.flutterRoot = '../..';
|
||||
return _testFile('test_async_utils_unguarded', 1);
|
||||
return _testFile('test_async_utils_unguarded', 1, automatedTestsDirectory, flutterTestDirectory);
|
||||
});
|
||||
testUsingContext('Missing flutter_test dependency', () async {
|
||||
final String missingDependencyTests = path.join('..', '..', 'dev', 'missing_dependency_tests');
|
||||
Cache.flutterRoot = '../..';
|
||||
return _testFile('trivial', 1, missingDependencyTests, missingDependencyTests);
|
||||
});
|
||||
}, timeout: new Timeout(const Duration(seconds: 5)));
|
||||
}
|
||||
|
||||
Future<Null> _testFile(String testName, int wantedExitCode) async {
|
||||
final String manualTestsDirectory = path.join('..', '..', 'dev', 'automated_tests');
|
||||
final String fullTestName = path.join(manualTestsDirectory, 'flutter_test', '${testName}_test.dart');
|
||||
Future<Null> _testFile(String testName, int wantedExitCode, String workingDirectory, String testDirectory) async {
|
||||
final String fullTestName = path.join(testDirectory, '${testName}_test.dart');
|
||||
final File testFile = fs.file(fullTestName);
|
||||
expect(testFile.existsSync(), true);
|
||||
final String fullTestExpectation = path.join(manualTestsDirectory, 'flutter_test', '${testName}_expectation.txt');
|
||||
final String fullTestExpectation = path.join(testDirectory, '${testName}_expectation.txt');
|
||||
final File expectationFile = fs.file(fullTestExpectation);
|
||||
expect(expectationFile.existsSync(), true);
|
||||
final ProcessResult exec = await Process.run(
|
||||
@ -44,14 +51,17 @@ Future<Null> _testFile(String testName, int wantedExitCode) async {
|
||||
'--no-color',
|
||||
fullTestName
|
||||
],
|
||||
workingDirectory: manualTestsDirectory
|
||||
workingDirectory: workingDirectory
|
||||
);
|
||||
expect(exec.exitCode, wantedExitCode);
|
||||
final List<String> output = exec.stdout.split('\n');
|
||||
output.add('<<stderr>>');
|
||||
output.addAll(exec.stderr.split('\n'));
|
||||
final List<String> expectations = fs.file(fullTestExpectation).readAsLinesSync();
|
||||
bool allowSkip = false;
|
||||
int expectationLineNumber = 0;
|
||||
int outputLineNumber = 0;
|
||||
bool haveSeenStdErrMarker = false;
|
||||
while (expectationLineNumber < expectations.length) {
|
||||
expect(output, hasLength(greaterThan(outputLineNumber)));
|
||||
final String expectationLine = expectations[expectationLineNumber];
|
||||
@ -68,10 +78,15 @@ Future<Null> _testFile(String testName, int wantedExitCode) async {
|
||||
}
|
||||
allowSkip = false;
|
||||
}
|
||||
if (expectationLine == '<<stderr>>') {
|
||||
expect(haveSeenStdErrMarker, isFalse);
|
||||
haveSeenStdErrMarker = true;
|
||||
}
|
||||
expect(outputLine, matches(expectationLine));
|
||||
expectationLineNumber += 1;
|
||||
outputLineNumber += 1;
|
||||
}
|
||||
expect(allowSkip, isFalse);
|
||||
expect(exec.stderr, '');
|
||||
if (!haveSeenStdErrMarker)
|
||||
expect(exec.stderr, '');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user