I am trying to create widget splash screen that shows when the app loads and the native splash screen is shown. I created the splash screen and everything seems fine so i decide to create widget test for the splash screen background image and single text on the screen. The test part for the text passes but i have issues with the image.
Widget test error text:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
Actual: _WidgetTypeFinder:<zero widgets with type "Image" (ignoring offstage widgets)>
Which: means none were found but one was expected
The full splash screen code:
class SplashScreenPage extends StatefulWidget {
const SplashScreenPage({Key? key}) : super(key: key);
@override
State<SplashScreenPage> createState() => _SplashScreenPageState();
}
class _SplashScreenPageState extends State<SplashScreenPage> {
Timer? _timer;
@override
void initState() {
_timer = Timer(const Duration(seconds: 4), () {
Navigator.of(context).pushReplacementNamed(RoutingConst.defaultRoute);
});
super.initState();
}
@override
void dispose() {
_timer!.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/background.png"),
fit: BoxFit.cover,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: [
const Spacer(),
const Spacer(),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child: Text(
"SPLASH SCREEN TEXT",
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: GoogleFonts.inter(
color: Colors.white,
fontSize: 40,
fontWeight: FontWeight.bold,
),
),
),
],
),
const Spacer(),
],
),
),
]
),
);
}
}
The widget test:
void main() {
//
// Setup
//
Widget createWidgetUnderTest() {
return const MaterialApp(
home: SplashScreenPage(),
);
}
//
// Testing
//
testWidgets(
"Check if splash screen text shows up",
(WidgetTester tester) async {
await tester.pumpWidget(createWidgetUnderTest());
expect(find.text("SPLASH SCREEN TEXT"), findsOneWidget);
},
);
testWidgets(
"Check if splash screen background shows up",
(WidgetTester tester) async {
await tester.pumpWidget(createWidgetUnderTest());
expect(find.byType(Image), findsOneWidget);
},
);
}
The test for the text passes, but the one for the image fails and i can't figure out why. I tried the find.image(AssetImage("asset-path")) but that didn't work aswell. Tried to put key on the container holding the box decoration in and then try to find the container in the test and it finds it so maybie i am doing something wrong in finding image inside box decoration but i don't know how to find it if that's the case.
The Problem:
The
SplashScreenPagedoes not contain an actual Image widget, so the finders below used in the test will fail to find anImagewidget.find.byType(Image)finds aWidgetof typeImage.find.image()finds aWidgetof typeImageorFadeInImage.Setting an image to a
Container'sdecorationdoes not create anImagewidget, so the finders are inappropriate for this test.The Solution:
Use find.byWidgetPredicate to find the actual
Widgetcontaining the image, in this case:Containerand add checks to specify the properties of theContaineryou're looking for.Here's the code: