I’m trying to test a button, but it keeps giving this error
═╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test:
Bad state: No element
When the exception was thrown, this was the stack:
#0 Iterable.single (dart:core/iterable.dart:670:25)
#1 WidgetController.element (package:flutter_test/src/controller.dart:394:30)
#2 WidgetController.ensureVisible (package:flutter_test/src/controller.dart:1567:73)
#3 main.<anonymous closure> (file:///C:/Users/user/Documents/app/test/widgests/button_test.dart:9:18)
#4 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:170:29)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)
The test description was:
Test button
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: Test button
✖ Test button
Exited (1)
//file button_test.dart
// ignore_for_file: depend_on_referenced_packages
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Test button', (tester) async {
final btnFinder = find.byKey(const Key('button'));
await tester.ensureVisible(btnFinder);
await tester.tap(btnFinder);
await tester.pumpAndSettle();
});
}
//file button.dart
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'inactivity/universal_tap_handler.dart';
class Button extends StatelessWidget {
const Button({
required this.label,
this.onTap,
this.icon,
this.height = 50,
this.width,
this.backgroundColor,
super.key,
});
final void Function()? onTap;
final String label;
final Widget? icon;
final double height;
final double? width;
final Color? backgroundColor;
@override
Widget build(BuildContext context) {
return SizedBox(
key: const Key('button'),
height: height,
width: width ?? double.infinity,
child: Card(
elevation: 5,
color: const Color(0xFFC2A79F),
margin: const EdgeInsets.all(0),
child: UniversalTapHandler(
onTap: onTap!,
child: Row(
children: [
// Label
Expanded(
child: Center(
child: AutoSizeText(
label.toUpperCase(),
maxLines: 1,
textAlign: TextAlign.left,
style: const TextStyle(
fontSize: 16,
color: Color(0xFFEDE0D2),
fontWeight: FontWeight.w800,
),
),
),
),
],
),
),
),
);
}
}
// file UniversalTapHandler
class UniversalTapHandler extends RawGestureDetector {
UniversalTapHandler({
required GestureTapCallback onTap,
required Widget child,
super.key,
}) : super(
gestures: <Type, GestureRecognizerFactory>{
_UniversalPointerHandler: GestureRecognizerFactoryWithHandlers<_UniversalPointerHandler>(
() => _UniversalPointerHandler(),
(instance) {
instance.onTap = onTap;
},
),
},
child: child,
);
}
class _UniversalPointerHandler extends TapGestureRecognizer {
@override
void rejectGesture(int pointer) {
acceptGesture(pointer);
}
}
2
Answers
It looks like you’re missing a
await tester.pumpWidget(Button());
at the very beginning of your test. If no widget is loaded in the tree,find.byKey
will fail.You haven’t setup(pump) the widget to test on. It will be