I'm stuck with a widget test and I could use some help
to reproduce the behavior please run the code sample below
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'home_page.dart';
void main() => runApp(
const ProviderScope(
child: MaterialApp(
home: Material(
child: MyHomePage(),
),
),
),
);
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
extension RoundX on double {
double roundToPrecision(int n) {
final f = pow(10, n);
return (this * f).round() / f;
}
}
final tasksPod = Provider<List<Future<void> Function()>>(
(ref) => [
for (var i = 0; i < 10; ++i)
() async {
await Future.delayed(kThemeAnimationDuration);
}
],
);
final progressPod = Provider.autoDispose<ValueNotifier<double>>((ref) {
final notifier = ValueNotifier<double>(0);
ref.onDispose(notifier.dispose);
return notifier;
});
class MyHomePage extends HookWidget {
const MyHomePage() : super(key: const ValueKey('MyHomePage'));
@override
Widget build(BuildContext context) {
final progress = useProvider(progressPod);
final tasks = useProvider(tasksPod);
useMemoized(() async {
final steps = tasks.length;
if (steps < 1) {
progress.value = 1;
} else {
for (final task in tasks) {
final current = progress.value;
if (current >= 1) {
break;
}
await task();
final value = (current + 1 / steps).roundToPrecision(1);
print('$value');
progress.value = value;
}
}
});
return Center(
child: ValueListenableBuilder<double>(
valueListenable: progress,
child: const FlutterLogo(),
builder: (context, value, child) =>
value < 1 ? const CircularProgressIndicator() : child!,
),
);
}
}
running the app everything is fine
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk... 4.7s
Syncing files to device Pixel 3a... 93ms
Flutter run key commands.
r Hot reload.
R Hot restart.
h Repeat this help message.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).
Running with sound null safety
An Observatory debugger and profiler on Pixel 3a is available at: http://127.0.0.1:36517/50vVndYZ3l4=/
I/flutter (19990): 0.1
I/flutter (19990): 0.2
I/flutter (19990): 0.3
I/flutter (19990): 0.4
I/flutter (19990): 0.5
I/flutter (19990): 0.6
I/flutter (19990): 0.7
The Flutter DevTools debugger and profiler on Pixel 3a is available at: http://127.0.0.1:9101?uri=http%3A%2F%2F127.0.0.1%3A36517%2F50vVndYZ3l4%3D%2F
I/flutter (19990): 0.8
I/flutter (19990): 0.9
I/flutter (19990): 1.0
Application finished.
but fails this test
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:timeout_issue/home_page.dart';
void main() {
testWidgets(
'WHEN tasks are not completed'
'THEN shows `CircularProgressIndicator`', (tester) async {
TestWidgetsFlutterBinding.ensureInitialized();
await tester.runAsync(() async {
await tester.pumpWidget(
ProviderScope(
child: const MaterialApp(
home: Material(
child: MyHomePage(),
),
),
),
);
await tester.pumpAndSettle(kThemeAnimationDuration);
expect(
find.byType(CircularProgressIndicator),
findsOneWidget,
reason: 'CircularProgressIndicator should be shown',
);
});
});
}
with this output
00:05 +0: WHEN tasks are not completedTHEN shows `CircularProgressIndicator`
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown while running async test code:
pumpAndSettle timed out
When the exception was thrown, this was the stack:
#0 WidgetTester.pumpAndSettle.<anonymous closure> (package:flutter_test/src/widget_tester.dart:651:11)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
00:05 +0 -1: WHEN tasks are not completedTHEN shows `CircularProgressIndicator` [E]
Test failed. See exception logs above.
The test description was: WHEN tasks are not completedTHEN shows `CircularProgressIndicator`
00:05 +0 -1: Some tests failed.
the environment is
Flutter version 2.2.0-11.0.pre.176
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
hooks_riverpod: ^0.14.0
flutter_hooks: ^0.16.0
any help is apprecciated
I'd say the problem is related to using pumpAndSettle and an infinite animation (Circular progress indicator). You can try using pump without the settle to build frames yourself.
https://api.flutter.dev/flutter/flutter_test/WidgetTester/pumpAndSettle.html