Osa*_*arf 0 testing unit-testing flutter flutter-test widget-test-flutter
这是我第一次测试 flutter 应用程序。HomeView我尝试用这个测试代码来泵:
void main() {\n group('Home Test', () {\n _pumpHome(WidgetTester tester) => tester.pumpWidget(\n MaterialApp(\n home: HomeView(),\n ),\n );\n\n testWidgets('Route to Azkar page', (WidgetTester tester) async {\n await _pumpHome(tester);\n await tester.tap(find.byKey(Key('morning')));\n expect(find.byType(ListView), findsOneWidget);\n });\n });\n}\nRun Code Online (Sandbox Code Playgroud)\n但这两个例外却发生了。
\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY WIDGETS LIBRARY \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following LateError was thrown building HomeView(dirty):\nLateInitializationError: Field '_instance@99075166' has not been initialized.\n\nThe relevant error-causing widget was:\n HomeView file:///E:/projects/flutterProject/tafra/test/home_test.dart:26:19\n\nWhen the exception was thrown, this was the stack:\n#0 ScreenUtil._instance (package:flutter_screenutil/screen_util.dart)\n#1 new ScreenUtil (package:flutter_screenutil/screen_util.dart:28:12)\n#2 SizeExtension.w (package:flutter_screenutil/size_extension.dart:5:19)\n#3 HomeView.build (package:tafra/app/modules/home/views/home_view.dart:23:27)\n#4 StatelessElement.build (package:flutter/src/widgets/framework.dart:4648:28)\n#5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)\n#6 Element.rebuild (package:flutter/src/widgets/framework.dart:4267:5)\n#7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4553:5)\n#8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4548:5)\n... Normal element mounting (166 frames)\n#174 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3611:14)\n#175 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6221:36)\n#176 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6232:32)\n... Normal element mounting (354 frames)\n#530 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3611:14)\n#531 Element.updateChild (package:flutter/src/widgets/framework.dart:3360:20)\n#532 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1189:16)\n#533 RenderObjectToWidgetElement.update (package:flutter/src/widgets/binding.dart:1167:5)\n#534 RenderObjectToWidgetElement.performRebuild (package:flutter/src/widgets/binding.dart:1181:7)\n#535 Element.rebuild (package:flutter/src/widgets/framework.dart:4267:5)\n#536 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2582:33)\n#537 AutomatedTestWidgetsFlutterBinding.drawFrame (package:flutter_test/src/binding.dart:1106:19)\n#538 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:328:5)\n#539 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)\n#540 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1082:9)\n#541 AutomatedTestWidgetsFlutterBinding.pump.<anonymous closure> (package:flutter_test/src/binding.dart:973:9)\n#544 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)\n#545 AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:960:27)\n#546 WidgetTester.pumpWidget.<anonymous closure> (package:flutter_test/src/widget_tester.dart:534:22)\n#549 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)\n#550 WidgetTester.pumpWidget (package:flutter_test/src/widget_tester.dart:531:27)\n#551 main.<anonymous closure>._pumpHome (file:///E:/projects/flutterProject/tafra/test/home_test.dart:19:46)\n#552 main.<anonymous closure>.<anonymous closure> (file:///E:/projects/flutterProject/tafra/test/home_test.dart:31:22)\n#553 main.<anonymous closure>.<anonymous closure> (file:///E:/projects/flutterProject/tafra/test/home_test.dart:30:40)\n#554 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:156:29)\n<asynchronous suspension>\n<asynchronous suspension>\n(elided 5 frames from dart:async and package:stack_trace)\n\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following assertion was thrown running a test:\nThe finder "zero widgets with key [<'morning'>] (ignoring offstage widgets)" (used in a call to\n"tap()") could not find any matching widgets.\n\nWhen the exception was thrown, this was the stack:\n#0 WidgetController._getElementPoint (package:flutter_test/src/controller.dart:897:7)\n#1 WidgetController.getCenter (package:flutter_test/src/controller.dart:836:12)\n#2 WidgetController.tap (package:flutter_test/src/controller.dart:271:18)\n#3 main.<anonymous closure>.<anonymous closure> (file:///E:/projects/flutterProject/tafra/test/home_test.dart:32:20)\n<asynchronous suspension>\n<asynchronous suspension>\n(elided one frame from package:stack_trace)\nRun Code Online (Sandbox Code Playgroud)\n我认为第二个例外的原因就是第一个例外。
\n我的HomeView生产代码:
class HomeView extends GetView<HomeController> {\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n drawer: Drawer(\n key: Key('drawer'),\n child: Column(\n children: [\n Image.asset(\n AppUi.assets.logo,\n height: 600.w,\n width: Get.width,\n fit: BoxFit.cover,\n ),\n DrawerListTile('\xd8\xa7\xd9\x84\xd8\xa3\xd8\xb3\xd8\xa6\xd9\x84\xd8\xa9', Icons.question_answer, () {\n Get.back();\n Get.toNamed(Routes.QUESTIONS);\n })\n ],\n ),\n ),\n backgroundColor: AppUi.colors.appSkyLight,\n appBar: TafraAppBar(\n titleText: '\xd8\xa7\xd9\x84\xd8\xb1\xd8\xa6\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa9',\n ),\n body: Column(\n mainAxisAlignment: MainAxisAlignment.center,\n children: [\n Row(\n mainAxisAlignment: MainAxisAlignment.spaceAround,\n children: [\n AzkarCard(\n '\xd8\xa3\xd8\xb0\xd9\x83\xd8\xa7\xd8\xb1 \xd8\xa7\xd9\x84\xd8\xb5\xd8\xa8\xd8\xa7\xd8\xad',\n Icons.wb_sunny,\n onTap: () => controller.routeToAzkar(AzkarType.morning),\n key: Key('morning'),\n ),\n AzkarCard(\n '\xd8\xa3\xd8\xb0\xd9\x83\xd8\xa7\xd8\xb1 \xd8\xa7\xd9\x84\xd9\x85\xd8\xb3\xd8\xa7\xd8\xa1',\n Icons.nightlight_round,\n onTap: () => controller.routeToAzkar(AzkarType.evening),\n key: Key('evening'),\n ),\n ],\n ),\n ],\n ),\n );\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n和是DrawerListTile自AzkarCard定义小部件。当我删除它们并将它们与Text小部件交换时,测试代码成功了!
所以我不知道我想测试的代码是否不应该有自定义小部件。这在实际项目中是不可能的。
\n问题已经解决了!
ScreenUtilInit中缺少此问题的原因MaterialApp。方法pumpWidget应该是这样的:
_pumpWidget(WidgetTester tester,) => tester.pumpWidget(
MaterialApp(
home: ScreenUtilInit(
designSize: Size(1080, 1920), builder: () => HomeView()),
),
);
Run Code Online (Sandbox Code Playgroud)