diff --git a/packages/flutter_tools/lib/src/test/coverage_collector.dart b/packages/flutter_tools/lib/src/test/coverage_collector.dart index 44e2e14a21..be30846906 100644 --- a/packages/flutter_tools/lib/src/test/coverage_collector.dart +++ b/packages/flutter_tools/lib/src/test/coverage_collector.dart @@ -177,6 +177,12 @@ class CoverageCollector extends TestWatcher { } return true; } + + @override + Future handleTestCrashed(ProcessEvent event) async { } + + @override + Future handleTestTimedOut(ProcessEvent event) async { } } Future _defaultConnect(Uri serviceUri) { diff --git a/packages/flutter_tools/lib/src/test/event_printer.dart b/packages/flutter_tools/lib/src/test/event_printer.dart index d5fa522214..7111e90b0f 100644 --- a/packages/flutter_tools/lib/src/test/event_printer.dart +++ b/packages/flutter_tools/lib/src/test/event_printer.dart @@ -22,6 +22,21 @@ class EventPrinter extends TestWatcher { _parent?.handleStartedProcess(event); } + @override + Future handleTestCrashed(ProcessEvent event) async { + return _parent.handleTestCrashed(event); + } + + @override + Future handleTestTimedOut(ProcessEvent event) async { + return _parent.handleTestTimedOut(event); + } + + @override + Future handleFinishedTest(ProcessEvent event) async { + return _parent.handleFinishedTest(event); + } + void _sendEvent(String name, [ dynamic params ]) { final Map map = {'event': name}; if (params != null) { diff --git a/packages/flutter_tools/lib/src/test/watcher.dart b/packages/flutter_tools/lib/src/test/watcher.dart index ea45b36cf3..9e0540b3e5 100644 --- a/packages/flutter_tools/lib/src/test/watcher.dart +++ b/packages/flutter_tools/lib/src/test/watcher.dart @@ -17,14 +17,14 @@ abstract class TestWatcher { /// /// The child process won't exit until this method completes. /// Not called if the process died. - Future handleFinishedTest(ProcessEvent event) async { } + Future handleFinishedTest(ProcessEvent event); /// Called when the test process crashed before connecting to test harness. - Future handleTestCrashed(ProcessEvent event) async { } + Future handleTestCrashed(ProcessEvent event); /// Called if we timed out waiting for the test process to connect to test /// harness. - Future handleTestTimedOut(ProcessEvent event) async { } + Future handleTestTimedOut(ProcessEvent event); } /// Describes a child process started during testing. diff --git a/packages/flutter_tools/test/integration.shard/coverage_collection_test.dart b/packages/flutter_tools/test/integration.shard/coverage_collection_test.dart new file mode 100644 index 0000000000..32d3475d12 --- /dev/null +++ b/packages/flutter_tools/test/integration.shard/coverage_collection_test.dart @@ -0,0 +1,35 @@ +// Copyright 2014 The Flutter 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:file/file.dart'; +import 'package:file_testing/file_testing.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; + +import '../src/common.dart'; + +import 'test_data/test_project.dart'; +import 'test_driver.dart'; +import 'test_utils.dart'; + +void main() { + Directory tempDir; + + setUp(() async { + tempDir = createResolvedTempDirectorySync('flutter_coverage_collection_test.'); + }); + + tearDown(() async { + tryToDelete(tempDir); + }); + + test('Can collect coverage in machine mode', () async { + final TestProject project = TestProject(); + await project.setUpIn(tempDir); + final FlutterTestTestDriver flutter = FlutterTestTestDriver(tempDir); + await flutter.test(coverage: true); + await flutter.done; + + expect(tempDir.childDirectory('coverage').childFile('lcov.info'), exists); + }); +} diff --git a/packages/flutter_tools/test/integration.shard/test_data/project.dart b/packages/flutter_tools/test/integration.shard/test_data/project.dart index b4dcef929f..cf43f9dce8 100644 --- a/packages/flutter_tools/test/integration.shard/test_data/project.dart +++ b/packages/flutter_tools/test/integration.shard/test_data/project.dart @@ -26,6 +26,7 @@ abstract class Project { String get pubspec; String get main; + String get test => null; Uri get mainDart => Uri.parse('package:test/main.dart'); @@ -35,6 +36,9 @@ abstract class Project { if (main != null) { writeFile(globals.fs.path.join(dir.path, 'lib', 'main.dart'), main); } + if (test != null) { + writeFile(globals.fs.path.join(dir.path, 'test', 'test.dart'), test); + } writeFile(globals.fs.path.join(dir.path, 'web', 'index.html'), _kDefaultHtml); await getPackages(dir.path); } diff --git a/packages/flutter_tools/test/integration.shard/test_data/test_project.dart b/packages/flutter_tools/test/integration.shard/test_data/test_project.dart new file mode 100644 index 0000000000..fc51f6953f --- /dev/null +++ b/packages/flutter_tools/test/integration.shard/test_data/test_project.dart @@ -0,0 +1,41 @@ +// Copyright 2014 The Flutter 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 'project.dart'; + +class TestProject extends Project { + + @override + final String pubspec = ''' + name: test + environment: + sdk: ">=2.0.0-dev.68.0 <3.0.0" + + dependencies: + flutter: + sdk: flutter + dev_dependencies: + flutter_test: + sdk: flutter + '''; + + @override + final String main = r''' +int foo(int bar) { + return bar + 2; +} + '''; + + @override + final String test = r''' + import 'package:flutter_test/flutter_test.dart'; + import 'package:test/main.dart'; + + void main() { + testWidgets('it can test', (WidgetTester tester) async { + expect(foo(2), 4); + }); + } +'''; +} diff --git a/packages/flutter_tools/test/integration.shard/test_driver.dart b/packages/flutter_tools/test/integration.shard/test_driver.dart index 0c3e0c9888..1f21b07d22 100644 --- a/packages/flutter_tools/test/integration.shard/test_driver.dart +++ b/packages/flutter_tools/test/integration.shard/test_driver.dart @@ -126,6 +126,8 @@ abstract class FlutterTestDriver { _stderr.stream.listen((String message) => _debugPrint(message, topic: '<=stderr=')); } + Future get done => _process.exitCode; + Future connectToVmService({ bool pauseOnExceptions = false }) async { _vmService = await vmServiceConnectUri('$_vmServiceWsUri'); _vmService.onSend.listen((String s) => _debugPrint(s, topic: '=vm=>')); @@ -680,6 +682,7 @@ class FlutterTestTestDriver extends FlutterTestDriver { String testFile = 'test/test.dart', bool withDebugger = false, bool pauseOnExceptions = false, + bool coverage = false, File pidFile, Future Function() beforeStart, }) async { @@ -687,6 +690,8 @@ class FlutterTestTestDriver extends FlutterTestDriver { 'test', '--disable-service-auth-codes', '--machine', + if (coverage) + '--coverage', ], script: testFile, withDebugger: withDebugger, pauseOnExceptions: pauseOnExceptions, pidFile: pidFile, beforeStart: beforeStart); }