Skip to content

Commit 77651bc

Browse files
authored
Reland "Fail tests on exceptions raised after test completed (#144706)" (#144980)
Reverts flutter/flutter#144970 No changes in this PR compared to the original. The test failure was fixed by adding missing awaits in flutter/flutter#144978. Fixes flutter/flutter#144353.
1 parent 394269f commit 77651bc

File tree

4 files changed

+54
-7
lines changed

4 files changed

+54
-7
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
7+
import 'package:flutter_test/flutter_test.dart';
8+
9+
// This is a test to make sure that an asynchronous exception thrown after a
10+
// test ended actually causes a test failure.
11+
// See //flutter/dev/bots/test.dart
12+
13+
void main() {
14+
final Completer<void> complete = Completer<void>();
15+
16+
testWidgets('test smoke test -- this test SHOULD FAIL', (WidgetTester tester) async {
17+
tester.runAsync(() async {
18+
Timer.run(() {
19+
complete.complete();
20+
throw StateError('Exception thrown after test completed.');
21+
});
22+
});
23+
});
24+
25+
tearDown(() async {
26+
print('Waiting for asynchronous exception...');
27+
await complete.future;
28+
});
29+
}

dev/bots/test.dart

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,26 @@ Future<void> _runTestHarnessTests() async {
346346
: 'Failed to find the stack trace for the pending Timer.\n\n'
347347
'stdout:\n${result.flattenedStdout}\n\n'
348348
'stderr:\n${result.flattenedStderr}';
349-
}),
349+
},
350+
),
351+
() => _runFlutterTest(
352+
automatedTests,
353+
script: path.join('test_smoke_test', 'fail_test_on_exception_after_test.dart'),
354+
expectFailure: true,
355+
printOutput: false,
356+
outputChecker: (CommandResult result) {
357+
const String expectedError = '══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════\n'
358+
'The following StateError was thrown running a test (but after the test had completed):\n'
359+
'Bad state: Exception thrown after test completed.';
360+
if (result.flattenedStdout!.contains(expectedError)) {
361+
return null;
362+
}
363+
return 'Failed to find expected output on stdout.\n\n'
364+
'Expected output:\n$expectedError\n\n'
365+
'Actual stdout:\n${result.flattenedStdout}\n\n'
366+
'Actual stderr:\n${result.flattenedStderr}';
367+
},
368+
),
350369
() => _runFlutterTest(
351370
automatedTests,
352371
script: path.join('test_smoke_test', 'crash1_test.dart'),

dev/bots/test/test_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,13 @@ void main() {
128128
<String, String>{'SHARD': kTestHarnessShardName, 'SUBSHARD': '1_3'},
129129
);
130130
expectExitCode(result, 0);
131-
expect(result.stdout, contains('Selecting subshard 1 of 3 (tests 1-3 of 8)'));
131+
expect(result.stdout, contains('Selecting subshard 1 of 3 (tests 1-3 of 9)'));
132132

133133
result = await runScript(
134134
<String, String>{'SHARD': kTestHarnessShardName, 'SUBSHARD': '3_3'},
135135
);
136136
expectExitCode(result, 0);
137-
expect(result.stdout, contains('Selecting subshard 3 of 3 (tests 7-8 of 8)'));
137+
expect(result.stdout, contains('Selecting subshard 3 of 3 (tests 7-9 of 9)'));
138138
});
139139

140140
test('exits with code 1 when SUBSHARD index greater than total', () async {

packages/flutter_test/lib/src/binding.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -910,15 +910,14 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
910910
// Ideally, once the test has failed we would stop getting errors from the test.
911911
// However, if someone tries hard enough they could get in a state where this happens.
912912
// If we silently dropped these errors on the ground, nobody would ever know. So instead
913-
// we report them to the console. They don't cause test failures, but hopefully someone
914-
// will see them in the logs at some point.
913+
// we raise them and fail the test after it has already completed.
915914
debugPrint = debugPrintOverride; // just in case the test overrides it -- otherwise we won't see the error!
916-
FlutterError.dumpErrorToConsole(FlutterErrorDetails(
915+
reportTestException(FlutterErrorDetails(
917916
exception: exception,
918917
stack: stack,
919918
context: ErrorDescription('running a test (but after the test had completed)'),
920919
library: 'Flutter test framework',
921-
), forceReport: true);
920+
), description);
922921
return;
923922
}
924923
// This is where test failures, e.g. those in expect(), will end up.

0 commit comments

Comments
 (0)